What better way to get around the “static variables” in Python?

后端 未结 3 529
情歌与酒
情歌与酒 2021-01-28 01:35

It seems that in Python, to declare a variable in a class, it is static (keeps its value in the next instances). What better way to get around this problem?

clas         


        
相关标签:
3条回答
  • 2021-01-28 02:24

    Just leave the declaration out. If you want to provide default values for the variables, initialize them in the __init__ method instead.

    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
    

    Edit: replaced last line of the above snippet; it used to read 1 although it was just a typo on my side. Seems like it has caused quite a bit of confusion while I was away.

    0 讨论(0)
  • 2021-01-28 02:25

    Variables defined at the class level are indeed "static", but I don't think they work quite the way you think they do. There are 2 levels here which you need to worry about. There are attributes at the class level, and there are attributes at the instance level. Whenever you do self.attribute = ... inside a method, you're setting an attribute at the instance level. Whenever python looks up an attribute, it first looks at the instance level, if it doesn't find the attribute, it looks at the class level.

    This can be a little confusing (especially if the attribute is a reference to a mutable object). consider:

    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']
    

    As others have mentioned, if you want an attribute to be specific to an instance, just initialize it as an instance attribute in __init__ (using self.attr = ...). __init__ is a special method which is run whenever a class is initialized (with a few exceptions that we won't discuss here).

    e.g.

    class Foo(object):
       def __init__(self):
           self.attr = 0
    
    0 讨论(0)
  • 2021-01-28 02:32

    You maybe want to change the class attribute:

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

    instead of overriding it!

    0 讨论(0)
提交回复
热议问题