有什么更好的方法来绕过Python中的“静态变量”?

时间:2012-08-28 14:42:23

标签: python

似乎在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

3 个答案:

答案 0 :(得分:7)

在班级定义的变量确实是“静态的”,但我认为它们并不像你认为的那样工作。这里有2个级别,您需要担心。 class 级别有属性,实例级别有属性。只要在方法中执行self.attribute = ...,就可以在实例级别设置属性。每当python查找一个属性时,它首先查看实例级别,如果它没有找到该属性,它会查看类级别。

这可能有点令人困惑(特别是如果属性是对 mutable 对象的引用)。考虑:

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__是一个特殊的方法,只要初始化一个类就会运行(有一些我们不会在这里讨论的例外)。

e.g。

class Foo(object):
   def __init__(self):
       self.attr = 0

答案 1 :(得分:1)

请留下声明。如果要为变量提供默认值,请改为使用__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,虽然这只是我身边的一个错字。在我离开的时候,似乎已经造成了相当多的混乱。

答案 2 :(得分:0)

您可能想要更改类属性:

class Foo():
    number = 0
    def set(self):
        Foo.number = 1

而不是覆盖它!