In Python, within a class, can a staticmethod call on another local function/method defined within the same class?
I tried the following code and obtained an error message saying foo1() is not defined.
a = 3.1
a = foo1()
obj = trialOne()
b = obj.foo()
class Tester: def local(self): print "I'm a local!" @staticmethod def another_stat(): print "I'm a static!" @staticmethod def stat(inst): inst.local() Tester.another_stat() t = Tester() Tester.stat(t) # Out: # I'm a local! # I'm a static!
Yes, you can! By definition, instance methods need an instance to associate themselves with, but as long as you have that instance, you can call local methods just as you normally would.
To go into this in a little more depth, there's nothing special about the word
self. That's a variable just like any other. Any instance method of a class MUST take in an instance of that class as its first parameter, and it's convention to call that parameter
self, but you could just as easily use any other name.
If it helps you understand the distinction, these two statements are semantically equivalent:
The first is just syntactic sugar for the second. The second is using the class name to reference a method of the Tester class, then passes in the instance as the first parameter. The first simply pretends that
local is a field of
t and calls it, but that call is transformed into
Tester.local(t) by the Python interpreter.
Thus, calling a static method is the same syntax as
Tester.local(t), except the first parameter does not have to be an instance of that class.
So classmethods and staticmethods are called in the same way, but the difference is that a class method "knows" what class it's coming from. The first parameter of a class method is always a variable that contains the class that it's being invoked from. That way if the method is inherited, it knows which method it's coming from, where a staticmethod would not know. In your comment, you said this:
@classmethod def stat(cls): cls.another_stat()
In this example,
cls is a variable that contains the class that the method is being called from, not an instance of the class that it is being called from. That is why you can call static methods with
cls - because it is equivalent to