Search code examples
pythonpython-3.xpython-class

Able to change class attributes without using a classmethod and staticmethod. Then what is the use of it?


In the below code snippet, no classmethod or staticmethod is used but class property can be altered just by defining normal methods inside a class, then what's the point? Am I missing something?

Can anyone please explain this behavior?

class test:
    var = 10
    def changeVariable():
        test.var = 100
    def reset():
        test.var = 10
>>> test.var
10
>>> test.changeVariable()
>>> test.var
100

Solution

  • Methods in a class are just functions. Function objects are non-data descriptors in python. That means that when you look up a method in an instance, it will be accessed from the class.

    Your example calls a bunch of functions. You can check this by doing

    >>> type(test.reset)
    

    The functions assign the var attribute of an object called test. The fact that test is a class is totally incidental here: you're just using it as a regular namespace.

    To see what happens when you try to bind one of these functions to an instance as a method, you need to create an instance:

    >>> inst = test()
    

    Now you can check that your functions are behaving as methods:

    >>> type(inst.reset)
    

    You'll get an error if you try to call inst.reset() though, because a bound method is a closure that passes the instance as a first implicit parameter:

    >>> inst.reset()
    

    As you correctly noted, the workaround is to either change the function signature, or wrap it in a staticmethod decorator.