14

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.

class trialOne(object):

    @staticmethod
    def foo1():
        a = 3.1
        return a

    @staticmethod
    def foo():
        a = foo1()
        return a

obj = trialOne()
b = obj.foo()
6
  • You say "local method". That's not a real term. What do you mean by that? Commented Aug 3, 2016 at 0:07
  • @user2357112: By that I mean a method "defined within the same class". Commented Aug 3, 2016 at 0:08
  • Have you tried it? Commented Aug 3, 2016 at 0:11
  • @IsmailBadawi: Of course I have tried. I failed earlier. C.f. my conversation with James below his answer. Commented Aug 3, 2016 at 0:44
  • Could the downvoter explain the reason for his downvote? Commented Aug 3, 2016 at 0:45

1 Answer 1

24
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:

t.local()

Tester.local(t)

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 Tester

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

8 Comments

I suppose that works when the method called is another static or class method, so long as we have the instance associating that method?
Not sure what you're asking - you can call a static method from another static method as well, if that's what you're asking. But you don't need an instance for that.
Yes, that is what I am asking. Is it true that I have to associate the static method being called with the instance like "inst" you used in the example?
I updated the answer - no, you do not. Static methods are not associated with instances, and are called just by referencing the class itself not any instance of it.
I see. Originally, I tried to use "self" or "cls" to do the same as follows but failed: @staticmethod def stat(cls[self]): cls[self].another_stat() The bracket around "self" or [self] means replacing "cls" with "self". So "self" or "cls" is different from the class name itself?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.