“私人"名称修改和实例与类属性
问题描述
我正在编写一个需要访问私有变量的装饰器并发现了这种差异.谁能解释一下?
I was writing a decorator that needs to access private variables and found this discrepancy. Can anyone explain this?
(Python 2.5)
(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...
更新
事实上,第二个例子也很好用.这是硬件问题(重启有帮助).
In fact, second example works fine, too. It was a hardware issue (restart helped).
解决方案
这其实是不正确的.
名称修改发生在类创建时;任何引用重整名称的函数也会被调整.
Name mangling takes place at class creation time; any functions that refer to mangled names are adjusted as well.
我无法重现您的示例,至少不能在 Mac 上的 Python 版本 2.4、2.5、2.6、3.1 和 3.2 中重现:
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
我检查了 编译器源代码 和 所有名称都通过 mangler 运行,这是一条至少从 2002 年以来一直保持不变的代码路径.
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.
是的,类属性和实例属性是正确的术语.类属性始终是共享的,但是将实例上的属性分配给 to 会分配给该实例.改变列表或其他可变对象与属性赋值不同.
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.
相关文章