4

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.

1
  • What you have is correct. It is also possible to use self for all 3. Commented Nov 3, 2017 at 4:32

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

2 Comments

I saw in the top answer in the referenced post saying that, a @classmethod is bounded to the class, and have to include a 'cls' just like 'self' for a normal class method. I am wondering are the 'cls' and 'self' has any actual meaning, so that we must use those 2 strings? And also why not use cls.class_foo(x) instead of self.class_foo(x)?
The names self and cls are conventions. You can use any name you want, but anyone reading your code will likely yell at you very loudly if you deviate from the normal conventions :-). In a classmethod, the first argument is the class whereas in a normal method, the first argument is an instance of the class. It's the difference between A and a in your example code. -- As to "why not use cls.class_foo(x)" -- You would use that if you were calling one classmethod from another classmethod. In an instance method, the name cls isn't defined (try it with my example code).
1

As @wim said, what you have is right. Here's the output when My_Question is called.

>>> a.My_Question("My_Answer=D")
executing foo(<__main__.A object at 0x0000015790FF4668>,My_Answer=D)
executing class_foo(<class '__main__.A'>,My_Answer=D)
executing static_foo(My_Answer=D)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.