Dra*_*mon 3 python setattr 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
Run Code Online (Sandbox Code Playgroud)
输出:
_MyClass__x
__y
Traceback (most recent call last):
...
AttributeError: __y
Run Code Online (Sandbox Code Playgroud)
该文档完全没有帮助说明“名称”是“属性的名称”,但由于某种原因,它会有所不同,具体取决于您是设置它还是获取它。
我想知道的是:
x第一种情况而不是_MyClass__x?双下划线调用名称修改。如果您不需要名称修饰,请不要使用双取消划线
\n\n\n\n\n\n\n\n9.6。私有变量
\n\n\xe2\x80\x9cPrivate\xe2\x80\x9d 实例变量只能从对象内部访问,Python 中不存在 \xe2\x80\x99t 。然而,大多数 Python 代码都遵循一个约定:以下划线前缀的名称(例如
\n\n_spam)应被视为 API 的非公共部分(无论是函数、方法还是数据成员)。它应被视为实施细节,如有更改,恕不另行通知。由于类私有成员有一个有效的用例(即避免名称与子类定义的名称发生名称冲突),因此对这种称为名称修饰的机制的支持有限。该形式的任何标识符
\n\n__spam(至少两个前导下划线,最多一个尾随下划线)在文本上都替换为_classname__spam,其中 classname 是删除了前导下划线的当前类名称。这种修改的完成与标识符的语法位置无关,只要它出现在类的定义中即可。请注意,损坏规则主要是为了避免事故而设计的;仍然可以访问或修改被视为私有的变量。这甚至在特殊情况下很有用,例如在调试器中。
\n\n请注意,传递给
\nexec,eval()or的代码execfile()并不将调用类的类名视为当前类;这类似于全局语句的效果,其效果同样仅限于字节编译在一起的代码。同样的限制适用于getattr()、setattr()和delattr()以及__dict__直接引用时。