Search code examples
pythonstatic-variables

Understanding behaviour of self with static variables


I am confused with the behaviour of self when it comes to dealing with static variables in python.From what I understand is that static variables can be accessed by either using classname.variablename or self.variablename. However changing the value of that variable differs. I realized that if i change the static variable value by classname.variablename=SomeValue the instance variable reflects that value however if I change the value of static variable using self.variablename=SomeValue the static variable does not change when access like classname.variablename from what I understand is that when I assign a value like self.variablename=SomeValue then an instance variable is created. Can somebody please shed a little light on this behaviour.

Example 1:

class bean:
    mycar="SomeCar"
    def test(self):
        bean.mycar = "yup"
        print(self.mycar) #prints yup

Example 2:

class bean:
        mycar="SomeCar"
        def test(self):
            self.mycar = "pup"
            print(bean.mycar) #SomeCar

Solution

  • Both classes and instances can have attributes.

    A class attribute is assigned to a class object. People sometimes call this a "static variable".

    An instance attribute is assigned to an instance ("instance variable").

    When an attribute of an object is read, a number of things happen (see Descriptor HowTo Guide), but the short version is:

    1. Try to read the attribute from the instance
    2. If that fails, try to read it from the class

    When it is written, then there is no such mechanism. It is written where it is written ;)

    See in example:

    class A(object):
        pass
    
    a = A()
    
    print A.value  # fails - there is no "value" attribute
    print a.value  # fails - there is no "value" attribute
    
    A.value = 7
    
    print A.value  # prints 7
    print a.value  # also prints 7 - there is no attribute on instance, but there is on class
    
    a.value = 11
    
    print A.value  # prints 7
    print a.value  # prints 11 - now there is an attribute on the instance
    
    a2 = A()
    
    print a2.value  # prints 7 - this instance has no "value", but the class has
    

    self?

    BTW, the self argument (in the question) is an instance, just like a is here.