Search code examples
pythonstatic-methods

Calling a static method with self vs. class name


Calling Python static methods using the class name is more common, but can be a real eye sore for long class names. Sometimes I use self within the same class to call the static methods, because I find it looks cleaner.

class ASomewhatLongButDescriptiveClassName:

   def __init__(self):
      # This works, but it's an eyesore
      ASomewhatLongButDescriptiveClassName.do_something_static()

      # This works too and looks cleaner.
      self.do_something_static()

   @staticmethod
   def do_something_static():
      print('Static method called.')

My understanding is that calling a static method with self gets interpreted as ClassName.static_method(self), where self would be ignored by the static method.
(EDIT: The above statement is only true for instance methods, not static methods)

Are there any concrete reasons why I should not use self to call static methods within the same class?

FWIW This is a sister question to Difference between calling method with self and with class name?, which deals with non-static methods.


Solution

  • You make a few statements that aren't entirely correct:

    Calling Python static methods using the class name is more common

    It's not more common, it's the only way to do so from outside the class. i.e.:

    class MyClass:
        @staticmethod
        def a_method():
            pass
    
    
    MyClass.a_method()
    

    In this example, self.a_method() would not work, as self would not refer to an instance of MyClass.

    calling a static method with self is the same as ClassName.static_method(self), where self would be ignored by the static method

    That's not actually the case, for example:

    class MyClass:
        @staticmethod
        def a_method():
            pass
    
        def another_method(self):
            # this is fine
            self.a_method()
            # this causes an error, as .a_method expects no arguments
            MyClass.a_method(self)
    

    self simply refers to the instance of the class that called an instance method (which has the self argument, which doesn't even have to be called self - it's just whatever the first parameter is called, self is the convention.

    You can call static methods on self, because self is an instance of the class that has the static method, and thus has the method. You can also call static methods on classes directly, because a static method doesn't require an object instance as a first argument - which is the point of the static method.

    You're fine using self.a_method() where you like, just keep in mind that self will refer to an object of the class the object was instanced as, not the specific class you mention.

    For example:

    class ClassA:
        @staticmethod
        def a_method():
            print('a')
    
        def another_method(self):
            # prints whatever a_method for the class of self prints
            self.a_method()
            # always prints 'a', as a_method for ClassA prints 'a'
            ClassA.a_method()
    
    
    class ClassB(ClassA):
        @staticmethod
        def a_method():
            print('b')
    
    
    a = ClassA()
    a.another_method()
    b = ClassB()
    b.another_method()
    

    The output:

    a
    a
    b
    a
    

    So, you see, there is a difference between calling from self. and from Class.