class Ball:
a = []
def __init__(self):
pass
def add(self,thing):
self.a.append(thing)
def size(self):
print len(self.a)
for i in range(3):
foo = Ball()
foo.add(1)
foo.add(2)
foo.size()
我希望回归:
2
2
2
但我明白了:
2
4
6
这是为什么?我发现通过在 init 中执行= [],我可以绕过这种行为,但我不清楚为什么。
答案 0 :(得分:4)
DOH
我只知道原因。
在上面的例子中,a是类属性,而不是数据属性 - 所有Balls()都共享它们。注释掉a = []并将其放入 init 块意味着它是一个数据属性。 (并且,我无法使用foo.a访问它,我不应该这样做。)看起来类属性就像类的静态属性一样,它们由所有实例共享。
哇。
但有一个问题:CodeCompletion很糟糕。在foo类中,我不能自我。(变量),因为它不是自动定义的 - 它是由函数定义的。我可以定义一个类变量并将其替换为数据变量吗?
答案 1 :(得分:2)
您可能想要做的是:
class Ball:
def __init__(self):
self.a = []
如果仅使用a = []
,它会在__init__
函数中创建一个局部变量,该函数在函数返回时消失。分配给self.a
会使它成为您所追求的实例变量。
对于半相关问题,请参阅change the value of default parameters for future callers。
答案 2 :(得分:1)
“我可以定义一个类变量并用数据变量替换它吗?”
没有。它们是分开的东西。类变量只存在一次 - 在类中。
你可以 - 精确代码完成 - 从一些类变量开始,然后在编写完类后删除这些代码行。但每当你忘记这样做,就不会发生任何好事。
更好的是尝试不同的IDE。 Komodo Edit的代码完成似乎是明智的。
如果你有这么多长名称的变量,代码完成实际上是有用的,也许你应该让你的类更小或使用更短的名称。认真。
我发现当你到达一个代码完成比烦人更有帮助的地方时,你已经超出了“保持一切在我脑中”的复杂性阈值。如果班级不适合我的大脑,那就太复杂了。