为什么__setattr__的“name”参数包含类,但__getattr__不包含?
下面的代码:为什么__setattr__的“name”参数包含类,但__getattr__不包含?
class MyClass():
def test(self):
self.__x = 0
def __setattr__(self, name, value):
print name
def __getattr__(self, name):
print name
raise AttributeError(name)
x = MyClass()
x.test()
x.__y
输出:
_MyClass__x
__y
Traceback (most recent call last):
...
AttributeError: __y
的文档是完全无用的,说明了“名”是“的属性名称”,但出于某种原因,它取决于是否是不同的你正在设置或获取它。
我想知道的是:
- 我做得根本错误的吗?
- 如何在第一种情况下获得
x
而不是_MyClass__x
?
双下划线调用名称修改。如果你不需要名字改编,不要使用双undescore
What is the meaning of a single- and a double-underscore before an object name?
9.6。私有变量
“私有”实例变量不能在对象内部被访问,在Python中不存在。但是,大多数Python代码都有一个约定:以下划线作为前缀的名称(例如
_spam
)应被视为API的非公开部分(无论它是函数,方法还是数据成员) 。它应该被视为实施细节,如有更改,恕不另行通知。由于类 - 私有成员有一个有效的用例(即避免名称与名称由子类定义名称冲突),所以对这种称为名称修改的机制的支持有限。任何标识符
__spam
(至少包含两个前导下划线,最多一个尾部下划线)的文本格式将被替换为_classname__spam
,其中,classname是当前类名称,前导下划线已剥离。只要它在类的定义内发生,就不会考虑标识符的语法位置。请注意,修改规则的设计主要是为了避免事故;它仍然可以访问或修改被认为是私有的变量。这在特殊情况下甚至是有用的,比如在调试器中。
请注意,传递给
exec
,eval()
或execfile()
的代码不会将调用类的类名称视为当前类;这与全局语句的效果类似,其效果同样局限于一起字节编译的代码。同样的限制适用于getattr()
,setattr()
和delattr()
,以及直接引用__dict__
时。
我不知道到底为什么发生这种情况,但如果你使用_x
而不是__x
它的作品如你所愿。
它被称为名称修改:http://docs.python.org/tutorial/classes.html#private-variables – SilentGhost 2010-03-05 11:58:32
确实。有趣的是'__x__'没有得名。 – 2010-03-05 12:04:00
@ar,'__x__'还有另一个特殊的含义 – 2010-03-05 12:05:28
糟糕,我错过了'__y'的下划线。我现在纠正了它。仍然存在不对称,但我认为你已经遇到了核心问题。 – Draemon 2010-03-05 12:01:35