Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 由类中的函数访问的变量_Python - Fatal编程技术网

Python 由类中的函数访问的变量

Python 由类中的函数访问的变量,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

为什么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

#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是,同意。这个问题实际上不是重复的。这个问题要简单得多,不需要解释公共和私人方法之间的区别。谢谢-这是一个非常清楚的解释,正是我想要的。谢谢-这是一个非常清楚的解释,正是我想要的。