class variables is shared across all instances in python?
我一周前开始用python进行编码,我的错误是我很快就开始用oops、类和对象进行编码。我假设我的C++熟练程度会有帮助。我被下面的代码咬了一口
1 2 3 4 5
| class A:
var=0
list=[]
def __init__(self):
pass |
令我惊讶的是,var和list是一个全局变量,它似乎在所有实例中都是共享的。我想这在所有的情况下都是不同的…..我花了半天时间才弄明白…一个变量只能由一个类对象访问,但在所有实例中共享,这一点毫无意义。只是好奇,这背后有什么原因吗???????
- 我对不属于类的类变量没有问题….但是为什么外面的所有变量都是静态的,去掉关键字static……。这违背了自然本能……
- @不管怎样,TechStuffWorks所有语言都有不同的语法,这只是您需要习惯的东西。由于python的动态特性,将变量绑定到其内部的内容(在本例中是类,而不是类的实例)是合理的。
- ^:)…………
只要您通过instance.var或self.var访问,就不应该共享var。然而,对于该列表,您的语句所做的是在对类进行计算时,将创建一个列表实例并将其绑定到类dict,因此所有实例都将具有相同的列表。无论何时,只要你设置了instance.list = somethingelseresp。self.list = somethingelse应该得到一个实例级的值。
示例时间:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| >>> class A():
... var = 0
... list = []
...
>>> a = A()
>>> b = A()
>>> a.var
0
>>> a.list
[]
>>> b.var
0
>>> b.list
[]
>>> a.var = 1
>>> b.var
0
>>> a.list.append('hello')
>>> b.list
['hello']
>>> b.list = ['newlist']
>>> a.list
['hello']
>>> b.list
['newlist'] |
- var和list的情况完全相同,区别在于不能像使用list那样附加到var上,只能声明另一个同名的变量。
- @在这种情况下,Brendanlong不可变类型是不同的,因为共享它们并不重要
- 是的,我只是想澄清一下,你共享的是不变的var,每当你做self.var = ...的时候,你也只是用别的东西来代替它。因此,var和list的行为完全相同,只是list作为共享变量更有趣(因为它是可变的)。
这些基本上像Java中的静态变量:
1 2 3 4 5
| // Example equivalent Java
class A {
static int var = 0;
static String[] list;
} |
这是预期的行为:类变量用于类。
对于普通实例变量,在构造函数中声明它们:
1 2 3 4
| class A:
def __init__(self):
self.var = 0
self.list = [] |
您可能需要查看Python中的静态类变量。
- 好吧,现在我尝试了一个exmaple,很肯定,列表是共享的…变量呢?它不是在所有实例之间共享的(我测试过它)……它仍然是静态的,在继续返回代码之前,我需要再学习吗?谢谢你的帮助……
- @另外一个变量也是静态的,但是如果您执行self.var="something else",那么您将设置一个同名的实例变量(您将同时使用A.var和self.var),并假定您是指实例变量。您仍然可以使用A.var访问类变量。通过使用相同的名称(self.list ="something else"声明实例方法,可以对list执行相同的操作。
- 是的,实际上我把所有东西都移到了"uuinit_uuuu()"下,这是另一个问题,我有一些变量需要是公共的,不可写的。像C++中的宏或者C++中的宏一样思考,我应该在哪里写呢?????
- @HowTechStuffWorks通常应该为每个问题打开一个新线程,但要回答这个问题,python没有常量。有一些黑客可以创建它们,但一般的解决方案是用大写字母命名常量,并假设您的API用户没有足够的笨来更改它们(您会发现这是Python中的一个常见主题——您可以做任何事情,但这并不意味着您应该这样做)。
原因是在python中,class是一个可执行语句,与其他语句一样执行。类定义的主体在定义类时执行一次。如果您在其中有一行var = [],那么它只执行一次,因此该行只能创建一个列表。
注意,您没有看到var的这种行为,您只看到list的这种行为:
1 2 3 4 5 6 7 8 9
| >>> class A:
... var = 0
... list = []
...
>>> a1 = A()
>>> a2 = A()
>>> a1.var = 3
>>> a2.var
0 |
- ^是的,同意了……但仍然令人困惑……
- 这是因为python在类变量之前查找实例变量。在您的var案例中,您添加了一个实例变量,该变量随后优先。
- @Brendanlong为什么var是一个实例变量,而list不是,如果它们的定义方式相同?