Can someone help me understand class variables

Solution 1:

The test() call is irrelevant. The print is executed during the definition of the test class. That is before Whatever is instantiated, so it is before the class attribute is set to 9999.

class Whatever():
    b = 5
    def __init__(self):
        Whatever.b = 9999

class test():
    print(Whatever.b)
# Now the print happens (while Whatever.b is still 5)

Whatever()
# Now Whatever.b is 9999
test()

If you check the value of Whatever.b any point after you have instantiated Whatever(), you will find that the value has indeed been changed to 9999.

Solution 2:

The problem is that the print statement in test happens when the class is defined, not when it is instantiated. Because it happens when it is defined, it happens before the call to Whatever() and thus b hasn't been reset.

It's unusual to put executable code in a class but outside of any methods. Contrast the behavior of your code with the output you get when you define Test like this:

class test():
    def __init__(self):
        print(Whatever.b)

When I make the above change, the output shows that b is now 9999. That is because the print statement happens when you create the instance of test rather than when you define the class, and because you create the instance after you've created an instance of Whatever.

Solution 3:

On the test() class you need to instantiate Whatever() like this:

    myWhatever = Whatever()
    print(myWhatever.b)

Then only run Test()

https://www.digitalocean.com/community/tutorials/understanding-class-and-instance-variables-in-python-3

Solution 4:

The problem is that the line test() isn't the line that make the 5 print out. I can run:

class Whatever():
    b = 5
    def __init__(self):
        Whatever.b = 9999

class test():
    print(Whatever.b)

Whatever()

and it will still output 5, since the print statement is run during the definition of the class test.

Basically what your class test does is print Whatever.b without initializing class Whatever so Whatever.b never gets set to 9999.

To get 9999 outputted you want to initialise Whatever first in the class definition, like this:

class Whatever():
    b = 5
    def __init__(self):
        Whatever.b = 9999

class test():
    Whatever()
    print(Whatever.b)

Whatever()