据我所知,类共享变量与类的所有实例共享。但我无法理解这一点。
class c():
a=[1]
b=1
def __init__(self):
pass
x=c()
x.a.append(1)
x.b+=1 #or x.b=2
print x.a #[1,1]
print x.b #2
y=c()
print y.a #[1,1] :As Expected
print y.b #1 :why not 2?
y.a 与 x.a 产生共鸣但是 y.b 没有。
希望有人能澄清。
编辑:如何为整数创建相同的功能。
答案 0 :(得分:10)
x.a.append(1)
通过调用c.a
方法更改类属性list
append
,该方法可就地修改列表。
x.b += 1
实际上是
的简写x.b = x.b + 1
因为Python中的整数是不可变的,所以它们没有__iadd__
(就地添加)方法。此分配的结果是在实例b
上设置属性x
,其值为2
(评估分配右侧的结果)。这个新的实例属性会影响类属性。
要查看就地操作和作业之间的区别,请尝试
x.a += [1]
和
x.a = x.a + [1]
这些会有不同的行为。
编辑通过装箱整数可以获得相同的功能:
class HasABoxedInt(object):
boxed_int = [0] # int boxed in a singleton list
a = HasABoxedInt()
a.boxed_int[0] += 1
b = HasABoxedInt()
print(b.boxed_int[0]) # prints 1, not zero
或
class BoxedInt(object):
def __init__(self, value):
self.value = value
def __iadd__(self, i):
self.value += i
答案 1 :(得分:2)
larsmans的答案非常好,但如果我们在分配之前和之后查看id
x.b
,它可能会提供额外的见解。
class c():
a=[1]
b=1
def __init__(self):
pass
x=c()
print "initial a : {} at {}".format(x.a, id(x.a))
print "initial b : {} at {}".format(x.b, id(x.b))
x.a.append(1)
x.b+=1 # x.b = x.b + 1, created a new object
# we created an instance variable x.b and it
# is shadowing the class variable b.
print "after change a : {} at {}".format(x.a, id(x.a))
print "after change b : {} at {}".format(x.b, id(x.b))
y=c()
# We can already see from the class object that
# b has not changed value
print "in class c b : {} at {}".format(c.b, id(c.b))
print "in instance y a : {} at {}".format(y.a, id(y.a))
print "in instance y b : {} at {}".format(y.b, id(y.b))
结果:
initial a : [1] at 50359040
initial b : 1 at 40974280
after change a : [1, 1] at 50359040
after change b : 2 at 40974256 # Shows id of instance variable x.b; hence it is
# different
in class c b : 1 at 40974280
in instance y a : [1, 1] at 50359040
in instance y b : 1 at 40974280
如果你想使用int
作为类变量,这应该有效:
class MyClass(object):
b=1
def increase_b(self, n):
MyClass.b += n
结果:
>>> mc_1 = MyClass()
>>> mc_1.b
1
>>> mc_1.increase_b(5)
>>> mc_1.b
6
>>> mc_2 = MyClass()
>>> mc_2.b
6
>>> mc_2.increase_b(10)
>>> MyClass.b
16
>>> mc_2.b
16
>>> mc_1.b
16