From a famous example, I learned the difference between method, classmethod and staticmethod in a Python class.
Source: What is the difference between @staticmethod and @classmethod in Python?
class A(object):
    def foo(self,x):
        print "executing foo(%s,%s)"%(self,x)
    @classmethod
    def class_foo(cls,x):
        print "executing class_foo(%s,%s)"%(cls,x)
    @staticmethod
    def static_foo(x):
        print "executing static_foo(%s)"%x   
    # My Guesses
    def My_Question(self,x):
        self.foo(x)
        A.class_foo(x)
        A.static_foo(x)
a=A()
Now I am wondering, how to call a method, @classmethod, and @staticmethod inside the class.
I put my guesses in the My_Question function above, please correct me if I am wrong with any of these.
Yes, your guesses will work. Note that it is also possible/normal to call staticmethods and classmethods outside the class:
class A():
    ...
A.class_foo()
A.static_foo()
Also note that inside regular instance methods, it's customary to call the staticmethods and class methods directly on the instance (self) rather than the class (A):
class A():
    def instance_method(self):
        self.class_foo()
        self.static_foo()
This allow for inheritance to work as you might expect -- If I create a B subclass from A, if I call B.instance_method(), my class_foo function will get B instead of A as the cls argument -- And possibly, if I override static_foo on B to do something slightly different than A.static_foo, this will allow the overridden version to be called as well.
Some examples might make this more clear:
class A(object):
    @staticmethod
    def static():
        print("Static, in A")
    @staticmethod
    def staticoverride():
        print("Static, in A, overrideable")
    @classmethod
    def clsmethod(cls):
        print("class, in A", cls)
    @classmethod
    def clsmethodoverrideable(cls):
        print("class, in A, overridable", cls)
    def instance_method(self):
        self.static()
        self.staticoverride()
        self.clsmethod()
        self.clsmethodoverride()
class B(A):
    @classmethod
    def clsmethodoverrideable(cls):
        print("class, in B, overridable", cls)
    @staticmethod
    def staticoverride():
        print("Static, in B, overrideable")
a = A()
b = B()
a.instance_method()
b.instance_method()
...
After you've run that, try it by changing all of the self. to A. inside instance_method.  Rerun and compare.  You'll see that all of the references to B have gone (even when you're calling b.instance_method()).  This is why you want to use self rather than the class.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With