Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Private" name mangling and instance vs class attributes

I was writing a decorator that needs to access private variables and found this discrepancy. Can anyone explain this?

(Python 2.5)

Naming mangling works as expected for attributes defined in the class:

>>> class Tester(object):
...    __foo = "hi"

>>> t = Tester()
>>> t._Tester__foo
'hi'

Instance attributes do not work (and this is the way we are supposed to do it right?)

>>> class Tester(object):
...     def __init__(self):
...         self.__foo = "hi"

>>> t = Tester()
>>> t._Tester__foo
AttributeError: 'Tester' object has no attribute '_Tester__foo'

P.S. Is "class attribute" the right word for these? They aren't static, but if you make one of those a list, or some other mutable type, it is shared...

Update

In fact, second example works fine, too. It was a hardware issue (restart helped).

like image 327
Rafe Avatar asked Sep 21 '12 20:09

Rafe


People also ask

What is the difference between class attributes and instance attributes?

Class attributes are the variables defined directly in the class that are shared by all objects of the class. Instance attributes are attributes or properties attached to an instance of a class. Instance attributes are defined in the constructor. Defined directly inside a class.

What is the difference between class attributes and instance attributes Java?

Instance attributes are owned by the specific instance of the class, meaning that these attributes can vary from instance to instance of a specific class. On the other hand, Class attributes are owned by the class itself, so the attribute has the same value for each instance of a particular class.

What is the difference between an attribute and an instance?

Classes contain characteristics called Attributes. We make a distinction between instance attributes and class attributes. Instance Attributes are unique to each object, (an instance is another name for an object). Here, any Dog object we create will be able to store its name and age.

What does it mean if a class attribute is private?

Private. In the context of class, private means the attributes are only available for the members of the class not for the outside of the class.


1 Answers

That is actually not correct.

Name mangling takes place at class creation time; any functions that refer to mangled names are adjusted as well.

I cannot reproduce your example, at least not in Python versions 2.4, 2.5, 2.6, 3.1 and 3.2 on the Mac:

>>> class Tester(object):
...     def __init__(self):
...         self.__foo = "hi"
... 
>>> Tester()._Tester__foo
'hi'
>>> Tester().__foo
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Tester' object has no attribute '__foo'

If you disassemble the function bytecode you can see the name has been mangled as well:

>>> import dis
>>> dis.dis(Tester.__init__)
  3           0 LOAD_CONST               1 ('hi')
              3 LOAD_FAST                0 (self)
              6 STORE_ATTR               1 (_Tester__foo)
              9 LOAD_CONST               0 (None)
             12 RETURN_VALUE        

I've checked the compiler source and all names are run through the mangler, a code path that has remained the same since 2002 at least.

And yes, class attributes and instance attributes are the correct terms. Class attributes are always shared, but assignment to an attribute on an instance assigns to the instance. Mutating a list or other mutable objects is not the same as attribute assignment.

like image 67
Martijn Pieters Avatar answered Sep 21 '22 17:09

Martijn Pieters