17

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.

7
  • 3
    "I understand that calling a static method with self is the same as ClassName.static_method(self) [...]" no it's not the same. That's only true for instance methods. Though you are using it correctly in your example, so I guess you are just misquoting a comment from the other linked SO question. Commented Dec 27, 2020 at 0:29
  • 3
    If you want to make use of a static method in the context of an instance method (e.g. __init__ in your example, then by all means use self. Of course, if you want to access the method from outside an instance, self will have no meaning, so you'll have to use the full class name. Commented Dec 27, 2020 at 0:32
  • 3
    Lets clarify what "outside an instance" means. If you have created foo = ASomewhatLongButDescriptiveClassName(), you should access the static method via foo.do_something_static(). Commented Dec 27, 2020 at 1:14
  • 1
    I would advise just stop using staticmethod and just use a regular, module-level function. Commented Dec 27, 2020 at 1:26
  • 1
    @DV82XL a better solution is probably to just not to make it a method at all and just make it a regular function, outside the class Commented Dec 27, 2020 at 3:42

2 Answers 2

35

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.

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

1 Comment

If you want to avoid repeating the class name in the call, an alternative to the ClassA.a_method() call inside another_method() is __class__.a_method(). This also always prints 'a', as a_method for ClassA prints 'a', and __class__ at this location is ClassA.
-1

Here are two examples of number formatting that use static functions: First, a simple thousands separator formatting method

class Car:

    def __init__(self, color: str, mileage: int):
        self.color: str = color
        self.mileage: int = mileage

    @staticmethod
    def format_with_comma_separator(amount: float) -> str:
        return f"{amount:,}"

    def __str__(self):
        # notice that mileage is printed with commas for thousands separation
        return f'The {self.color} car has {Car.format_with_comma_separator(self.mileage)} miles.'

Second example formats a floating point number as US-EN currency:

import locale

class Truck:

    def __init__(self, color: str, mileage: int, cost: float):
        self.color: str = color
        self.mileage: int = mileage
        self.cost: float = cost

    @staticmethod
    def format_currency(amount: float) -> str:
        # set locale to US
        locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')
        # format currency value
        return locale.currency(amount, grouping=True)

    def __str__(self):
        # notice that mileage is printed with commas for thousands separation and cost is formatted as currency (US)
        return f'The {self.color} truck has {self.mileage:,} miles and costs {Truck.format_currency(self.cost)}.'

1 Comment

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.