Python 由类中的函数访问的变量
为什么val_n函数返回旧的self值。\u n?在我看来,如果obj.\u n已更新为3,则调用self.val\u n应返回3而不是2Python 由类中的函数访问的变量,python,Python,为什么val_n函数返回旧的self值。\u n?在我看来,如果obj.\u n已更新为3,则调用self.val\u n应返回3而不是2 class myClass: def __init__(self,n=1): self.__n=n def val_n(self): return self.__n #create an instance, __n is 2 obj=myClass(2) #update __n to 3 obj.__n=3
class myClass:
def __init__(self,n=1):
self.__n=n
def val_n(self):
return self.__n
#create an instance, __n is 2
obj=myClass(2)
#update __n to 3
obj.__n=3
#verify obj.__n has changed from 2 to 3
print(obj.__n)
#why does this still return 2?
print(obj.val_n())
这是基于Python的名称混乱特性。类属性使用前导双下划线意味着Python将使用名称混乱
class X:
__attr = None
x = X()
x.__attr
# raises AttributeError
x._X__attr
# None
Python将类X
中的名称\uuuu attr
转换为\ux\uu attr
,这样在子类化时,如果子类还定义了\uu attr
但需要父类的属性,则该属性不太可能被覆盖
当您执行
x.\uu n=3
时,您不会覆盖类中定义的属性,因为该属性已成为x.\u myClass\uu n
。相反,您正在创建一个新属性(Python在分配它之前不会真正检查x.\uu n
,以查看它是否已经是对象的属性-这就是为什么没有出现AttributeError
。这是基于Python的名称篡改功能。类属性使用前导双下划线意味着Python将使用名称混乱
class X:
__attr = None
x = X()
x.__attr
# raises AttributeError
x._X__attr
# None
Python将类X
中的名称\uuuu attr
转换为\ux\uu attr
,这样在子类化时,如果子类还定义了\uu attr
但需要父类的属性,则该属性不太可能被覆盖
当您执行
x.\uu n=3
时,您不会覆盖类中定义的属性,因为该属性已成为x.\u myClass\uu n
。相反,您正在创建一个新属性(Python在分配它之前并没有真正检查x.\uu n
,以查看它是否已经是对象的属性-这就是为什么没有提出AttributeError
。副本没有说明为什么obj.\uu n=3
似乎会更改值。答案是,由于此赋值不在方法定义内,因此会创建一个新属性,其名称实际上是\uuu n
,而不是\uMyClass\uu n
。使用dir(obj)
显示赋值后存在两个名称的属性。@chepner是,同意。这个问题实际上不是重复的。这个问题要简单得多,不需要说明公共方法和私有方法之间的区别。副本没有说明为什么obj.\uu n=3
似乎会改变值。答案是,由于此赋值不在方法定义内,因此会创建一个新属性,其名称实际上是\uuu n
,而不是\uMyClass\uu n
。使用dir(obj)
显示赋值后存在两个名称的属性。@chepner是,同意。这个问题实际上不是重复的。这个问题要简单得多,不需要解释公共和私人方法之间的区别。谢谢-这是一个非常清楚的解释,正是我想要的。谢谢-这是一个非常清楚的解释,正是我想要的。