3

据我所知,类共享变量与类的所有实例共享。但是我很难理解这一点。

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?

ya与xa产生共鸣,但 yb没有。

希望有人能澄清一下。

编辑:以及如何为整数创建相同的功能。

4

2 回答 2

10
x.a.append(1)

通过调用其方法更改类属性c.aa ,该方法就地修改列表。listappend

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
于 2013-08-24T15:27:07.880 回答
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

如果您想使用 anint作为类变量,这应该有效:

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
于 2013-08-25T02:55:20.090 回答