Reputation: 23
Consider the following code:
def __g_fun():
pass
__a = 3
a=3
class Test(object):
def __init__(self):
global a,__a
print "locals:",locals()
print "global:",globals()
self.aa = __a
def fun(self):
return __g_fun()
t=Test()
t.fun()
Output:
locals: {'self': <__main__.Test object at 0x7f53580d50d0>}
global: {'__g_fun': <function __g_fun at 0x7f53580c52a8>, 'a': 3, '__a': 3, '__builtins__': <module '__builtin__' (built-in)>, '__file__': 'test.py', '__package__': None, 'Test': <class '__main__.Test'>, '__name__': '__main__', '__doc__': None}
Traceback (most recent call last):
File "test.py", line 19, in <module>
t=Test()
File "test.py", line 11, in __init__
self.aa = __a
NameError: global name '_Test__a' is not defined
Is it the case that variable with double underscore cannot be used in class?
Upvotes: 2
Views: 134
Reputation: 58831
Any identifier of the form
__spam
(at least two leading underscores, at most one trailing underscore) is textually replaced with_classname__spam
, where classname is the current class name with leading underscore(s) stripped.
Upvotes: 1
Reputation: 110476
Indeed - a double underline prefix inside a class code is treated in a special way by the Python compiler -
at compile time, such variables are name mangled to include the class name as a prefix -
so that the name __a
anywhere inside the class Test
will be changed to _Test__a
. (remembering that "compile time" is often transparent to the user, and can be taken as "at the time the program is run")
That is a feature meant to allow one to have names that are assessed in methods of a class, and not by its subclasses (not in an automatic form) - a feature that in some other languages is carried out by the "private" member modifier.
Check the Python class documentation at: https://docs.python.org/2/tutorial/classes.html#private-variables-and-class-local-references
Upvotes: 4