@staticmethod or function outside class?

This is a textbook use case for a private static method.

They key point here is that you should make it a private method of that class. That way you're certain nothing else will use it and depend on its implementation. You'll be free to change it in the future, or even delete it, without breaking anything outside that class.

And yeah, make it static, because you can.

In Python, there is no way to make a method truly private, but by convention, prefixing the method name by a _ means it should be treated as private.

    @staticmethod
    def _adder(a,b):  ## <-- note the _
        return a+b

If at some point you suddenly need to use it outside the class, then exposing it will be no trouble at all, e.g. using a public wrapper method.

The reverse, however, isn't true; once exposed, it's difficult to retract that exposure.


I would definitely use a private static method in this case, for the reasons described by Jean-Francois Corbett. There are two types of methods in Python that belong to the class itself, rather than an instance: class methods and static methods.

The first parameter of a class method (created with @classmethod) references the class in exactly the same manner that the first parameter of an instance method (self) references an instance. It is the equivalent of static methods in most other languages. If your method requires access to other class members, use a class method.

A static method (created with @staticmethod) does not contain a reference to the class, and therefore cannot reference other class members. It's generally used for private helper methods and the like.

For your adder method, I would definitely use a static method. However, in this modified (and rather useless) version, a class method is necessary:

class A:
    x = 1
    def __init__(self, my_int):
        self.my_int = my_int
    def my_int_and_4(self):
        print(self._adder(self.my_int,4))
    @staticmethod
    def _adder(a,b):
        return a+b
    @classmethod
    def _increment(cls, n):
        return n + cls.x

Both approaches will work, so it's the matter of readability and following conventions.

  • Does the method need to look at the instance's private attributes? If yes, it's a good reason to keep it in the class.
  • Is the method only used as a helper for one of different methods? If yes, it's a good reason to put it right after the calling method so that the code can be read top-down.
  • Does the method seem to make sense outside of the context of your class? If yes, it's a good reason to make it a free function or even move it to a different file, like utils.