似乎在 Python 中,要在类中声明一个变量,它是静态的(在下一个实例中保留它的值)。有什么更好的方法来解决这个问题?
class Foo():
number = 0
def set(self):
self.number = 1
>>> foo = Foo()
>>> foo.number
0
>>> foo.set()
>>> foo.number
1
>>> new_foo = Foo()
>>> new_foo.number
1
似乎在 Python 中,要在类中声明一个变量,它是静态的(在下一个实例中保留它的值)。有什么更好的方法来解决这个问题?
class Foo():
number = 0
def set(self):
self.number = 1
>>> foo = Foo()
>>> foo.number
0
>>> foo.set()
>>> foo.number
1
>>> new_foo = Foo()
>>> new_foo.number
1
在类级别定义的变量确实是“静态的”,但我认为它们的工作方式并不像您认为的那样。这里有 2 个级别,您需要担心。有类级别的属性,也有实例级别的属性。每当您self.attribute = ...
在方法中执行操作时,您都是在实例级别设置属性。每当python查找一个属性时,它首先查找实例级别,如果没有找到该属性,它会查找类级别。
这可能有点令人困惑(特别是如果属性是对可变对象的引用)。考虑:
class Foo(object):
attr = [] #class level attribute is Mutable
def __init__(self):
# in the next line, self.attr references the class level attribute since
# there is no instance level attribute (yet)
self.attr.append('Hello')
self.attr = []
# Now, we've created an instance level attribute, so further appends will
# append to the instance level attribute, not the class level attribute.
self.attr.append('World')
a = Foo()
print (a.attr) #['World']
print (Foo.attr) #['Hello']
b = Foo()
print (b.attr) #['World']
print (Foo.attr) #['Hello', 'Hello']
正如其他人所提到的,如果您希望属性特定于实例,只需将其初始化为__init__
(使用self.attr = ...
)中的实例属性。 __init__
是一个特殊的方法,它在类被初始化时运行(有一些我们不会在这里讨论的例外)。
例如
class Foo(object):
def __init__(self):
self.attr = 0
只留下声明。如果要为变量提供默认值,请__init__
改为在方法中初始化它们。
class Foo(object):
def __init__(self):
self.number = 0
def set(self):
self.number = 1
>>> foo = Foo()
>>> foo.number
0
>>> foo.set()
>>> foo.number
1
>>> new_foo = Foo()
>>> new_foo.number
0
编辑:替换了上述代码段的最后一行;它曾经读过,1
虽然这只是我这边的一个错字。好像在我不在的时候引起了很多混乱。
您可能想要更改类属性:
class Foo():
number = 0
def set(self):
Foo.number = 1
而不是覆盖它!