Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/317.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.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_Oop - Fatal编程技术网

Python类变量或一般的类变量

Python类变量或一般的类变量,python,oop,Python,Oop,从《深入Python》开始: 类属性通过直接引用 类并通过该类的任何实例 类属性可以用作类级常量,但它们是 不完全是常数。你也可以改变它们 因此,我将其输入IDLE: IDLE 2.6.5 >>> class c: counter=0 >>> c <class __main__.c at 0xb64cb1dc> >>> v=c() >>> v.__class__ <class

从《深入Python》开始:

类属性通过直接引用 类并通过该类的任何实例

类属性可以用作类级常量,但它们是 不完全是常数。你也可以改变它们

因此,我将其输入IDLE:

IDLE 2.6.5      
>>> class c:
        counter=0


>>> c
<class __main__.c at 0xb64cb1dc>
>>> v=c()
>>> v.__class__
<class __main__.c at 0xb64cb1dc>
>>> v.counter += 1
>>> v.counter
1
>>> c.counter
0
>>> 
IDLE 2.6.5
>>>c类:
计数器=0
>>>c
>>>v=c()
>>>五级__
>>>v.计数器+=1
>>>v.计数器
1.
>>>c.计数器
0
>>> 

那么我做错了什么?为什么类变量不能通过直接引用类和通过类的任何实例来保持其值。

您被混淆在声明实例化之间

C是您声明的类的名称


v是一个对象,从c实例化。

您的对象被混淆在声明实例化之间

C是您声明的类的名称


v是一个对象,从c.实例化。

因为int在python中是不可变的

v.counter += 1
v.counter
重新绑定到新的int对象。重新绑定将创建一个实例属性来屏蔽class属性

如果查看
v.counter的
id()
可以看到这种情况

>>> id(v.counter)
149265780
>>> v.counter+=1
>>> id(v.counter)
149265768
在这里,您可以看到
v
现在在其
\uuuuuu dict\uuuuu
中有一个新属性

>>> v=c()
>>> v.__dict__
{}
>>> v.counter+=1
>>> v.__dict__
{'counter': 1}
对比一下
计数器
可变的情况,例如
列表

>>> class c:
...  counter=[]
... 
>>> v=c()
>>> v.counter+=[1]
>>> c.counter
[1]
>>> 

因为int在python中是不可变的

v.counter += 1
v.counter
重新绑定到新的int对象。重新绑定将创建一个实例属性来屏蔽class属性

如果查看
v.counter的
id()
可以看到这种情况

>>> id(v.counter)
149265780
>>> v.counter+=1
>>> id(v.counter)
149265768
在这里,您可以看到
v
现在在其
\uuuuuu dict\uuuuu
中有一个新属性

>>> v=c()
>>> v.__dict__
{}
>>> v.counter+=1
>>> v.__dict__
{'counter': 1}
对比一下
计数器
可变的情况,例如
列表

>>> class c:
...  counter=[]
... 
>>> v=c()
>>> v.counter+=[1]
>>> c.counter
[1]
>>> 
之前:

c.counter = 0
v.counter -> c.counter
在:

c.counter = 0
v.counter = c.counter + 1
之后:

c.counter = 0
v.counter = 1
之前:

c.counter = 0
v.counter -> c.counter
在:

c.counter = 0
v.counter = c.counter + 1
之后:

c.counter = 0
v.counter = 1

请注意,您仍然可以获取类值:

v.__class__.__dict__['counter'] 

将允许您读取或设置类,即使您通过向实例的uuu dict_uuu添加符号来模糊符号。

请注意,您仍然可以获取类值:

v.__class__.__dict__['counter'] 

将允许您读取或设置类,即使您通过将符号添加到实例的“dict”中使符号变得模糊。

我将其命名为:一个新的int对象。。。对于
v.counter
我会说:一个新的int对象。。。到
v.counter
,因为c.counter仍然是0,您显然没有更改它的值。但是,您确实更改了v实例的counter属性的值。我认为您正在寻找“静态类变量”。由于c.counter仍然是0,所以很可能是的副本,您显然没有更改其值。但是,您确实更改了v实例的counter属性的值。我认为您正在寻找“静态类变量”。可能是它的一个复制品,这不是这里的困惑。如果你在一个类上设置了一个变量,你可以完全按照上面的方式来读取它:instance.classvariable。这不是这里的混淆。如果在类上设置了变量,则可以按照上面的方式正确读取:instance.classvariable。