Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6706555
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 26, 20262026-05-26T07:32:03+00:00 2026-05-26T07:32:03+00:00

I’ve just run into a situation where pseudo -private class member names aren’t getting

  • 0

I’ve just run into a situation where pseudo-private class member names aren’t getting mangled when using setattr or exec.

In [1]: class T:
   ...:     def __init__(self, **kwargs):
   ...:         self.__x = 1
   ...:         for k, v in kwargs.items():
   ...:             setattr(self, "__%s" % k, v)
   ...:         
In [2]: T(y=2).__dict__
Out[2]: {'_T__x': 1, '__y': 2}

I’ve tried exec("self.__%s = %s" % (k, v)) as well with the same result:

In [1]: class T:
   ...:     def __init__(self, **kwargs):
   ...:         self.__x = 1
   ...:         for k, v in kwargs.items():
   ...:             exec("self.__%s = %s" % (k, v))
   ...:         
In [2]: T(z=3).__dict__
Out[2]: {'_T__x': 1, '__z': 3}

Doing self.__dict__["_%s__%s" % (self.__class__.__name__, k)] = v would work, but __dict__ is a readonly attribute.

Is there another way that I can dynamically create these psuedo-private class members (without hard-coding in the name mangling)?


A better way to phrase my question:

What does python do “under the hood” when it encounters a double underscore (self.__x) attribute being set? Is there a magic function that is used to do the mangling?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-26T07:32:04+00:00Added an answer on May 26, 2026 at 7:32 am

    I believe Python does private attribute mangling during compilation… in particular, it occurs at the stage where it has just parsed the source into an abstract syntax tree, and is rendering it to byte code. This is the only time during execution that the VM knows the name of the class within whose (lexical) scope the function is defined. It then mangles psuedo-private attributes and variables, and leaves everything else unchanged. This has a couple of implications…

    • String constants in particular are not mangled, which is why your setattr(self, "__X", x) is being left alone.

    • Since mangling relies on the lexical scope of the function within the source, functions defined outside of the class and then “inserted” do not have any mangling done, since the information about the class they “belong to” was not known at compile-time.

    • As far as I know, there isn’t an easy way to determine (at runtime) what class a function was defined in… At least not without a lot of inspect calls that rely on source reflection to compare line numbers between the function and class sources. Even that approach isn’t 100% reliable, there are border cases that can cause erroneous results.

    • The process is actually rather indelicate about the mangling – if you try to access the __X attribute on an object that isn’t an instance of the class the function is lexically defined within, it’ll still mangle it for that class… letting you store private class attrs in instances of other objects! (I’d almost argue this last point is a feature, not a bug)

    So the variable mangling is going to have to be done manually, so that you calculate what the mangled attr should be in order to call setattr.


    Regarding the mangling itself, it’s done by the _Py_Mangle function, which uses the following logic:

    • __X gets an underscore and the class name prepended. E.g. if it’s Test, the mangled attr is _Test__X.
    • The only exception is if the class name begins with any underscores, these are stripped off. E.g. if the class is __Test, the mangled attr is still _Test__X.
    • Trailing underscores in a class name are not stripped.

    To wrap this all up in a function…

    def mangle_attr(source, attr):
        # return public attrs unchanged
        if not attr.startswith("__") or attr.endswith("__") or '.' in attr:
            return attr
        # if source is an object, get the class
        if not hasattr(source, "__bases__"):
            source = source.__class__
        # mangle attr
        return "_%s%s" % (source.__name__.lstrip("_"), attr)
    

    I know this somewhat “hardcodes” the name mangling, but it is at least isolated to a single function. It can then be used to mangle strings for setattr:

    # you should then be able to use this w/in the code...
    setattr(self, mangle_attr(self, "__X"), value)
    
    # note that would set the private attr for type(self),
    # if you wanted to set the private attr of a specific class,
    # you'd have to choose it explicitly...
    setattr(self, mangle_attr(somecls, "__X"), value)
    

    Alternately, the following mangle_attr implementation uses an eval so that it always uses Python’s current mangling logic (though I don’t think the logic laid out above has ever changed)…

    _mangle_template = """
    class {cls}:
        @staticmethod
        def mangle():
            {attr} = 1
    cls = {cls}
    """
    
    def mangle_attr(source, attr):
        # if source is an object, get the class
        if not hasattr(source, "__bases__"):
            source = source.__class__
        # mangle attr
        tmp = {}
        code = _mangle_template.format(cls=source.__name__, attr=attr)
        eval(compile(code, '', 'exec'), {}, tmp); 
        return tmp['cls'].mangle.__code__.co_varnames[0]
    
    # NOTE: the '__code__' attr above needs to be 'func_code' for python 2.5 and older
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

link Im having trouble converting the html entites into html characters, (&# 8217;) i
I have just tried to save a simple *.rtf file with some websites and
That's pretty much it. I'm using Nokogiri to scrape a web page what has
I have a string like this: La Torre Eiffel paragonata all’Everest What PHP function
this is what i have right now Drawing an RSS feed into the php,
I am reading a book about Javascript and jQuery and using one of the
I have a French site that I want to parse, but am running into
I'm using v2.0 of ClassTextile.php, with the following call: $testimonial_text = $textile->TextileRestricted($_POST['testimonial']); ... and
I am currently running into a problem where an element is coming back from
I'm parsing an RSS feed that has an ’ in it. SimpleXML turns this

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.