Unable to access module attribute with underscores in class method, Python 3

Peter Otten __peter__ at web.de
Fri Jan 8 08:49:11 EST 2016


Joseph Fox-Rabinovitz wrote:

> Hi,
> 
> I have a module attribute whose name starts with a pair of underscores. I
> am apparently unable to access it directly in a class method (within the
> same module, but that is not relevant as far as I can tell). The following
> bit of code illustrates the situation:
> 
> __a = 3
> class B:
>     def __init__(self):
>         global __a
>         self.a = __a
> b = B()
> 
> This results in a NameError because of name-mangling, despite the global
> declaration:
> 
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
>   File "<stdin>", line 4, in __init__
> NameError: name '_B__a' is not defined
> 
> Not using global does not make a difference. I posted a similar question
> on Stack Overflow, where the only reasonable answer given was to wrap __a
> in a container whose name is not mangled. For example, doing `self.a =
> globals()['__a']` or manually creating a dictionary with a non-mangled
> name and accessing that.
> 
> I feel that there should be some way of accessing __a within the class
> directly in Python 3. Clearly my expectation that global would fix the
> issue is incorrect. I would appreciate either a solution or an explanation
> of what is going on that would convince me that accessing a module
> attribute in such a way should be forbidden.

The explanation is obvious: the approach taken by the compiler is very 
simple, and all names with two leading underscores (an no two trailing ones 
of course) are mangled. Other than improving the compiler you can wrap 
access to __a in a function defined outside the class

def get_a():
    return __a

class B:
    def __init__(self):
        self.a = get_a()

Or, the horror, you change the name __a to _a.





More information about the Python-list mailing list