Assuming I have a class
which requires a function (or should I say method) which is:
class
instance - doesn't need self
argument;class
objectshould I (A) place it inside the class
and mark it as a @staticmethod
or should I (B) define it outside my class
object (but in the same namespace)? Why?
Example:
class A:
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
or
def adder(a,b):
return a+b
class B:
def __init__(self, my_int):
self.my_int = my_int
def my_int_and_4(self):
print(adder(self.my_int,4))
EDIT: maybe the example is a bit oversimplified. I should have added that my version of "adder
" is specificly used with my class
and in no other case.
Whenever the definition of a class member appears outside of the class declaration, the member name must be qualified by the class name using the :: (scope resolution) operator. The following example defines a member function outside of its class declaration.
Yes you can definitely have functions outside of a class.
Yes. You can use the static method if it is declared as public : public static void f() { // ... } or if it is package-private (no modifier):
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.
We generally use static methods to create utility functions. How to define a class method and a static method? To define a class method in python, we use @classmethod decorator, and to define a static method we use @staticmethod decorator. Let us look at an example to understand the difference between both of them.
Hereis a short article on this question @staticmethod function is nothing more than a function defined inside a class. It is callable without instantiating the class first. It’s definition is immutable via inheritance.
Putting such methods outside of a class, as functions, allows for reusing them by unrelated code. Depending on your current context and predictable future of the project - either can be better solution. Show activity on this post.
@classmethoddecorator can be called with with an instance of a class or directly by the class itself as its first argument. @staticmethodis a way of putting a function into a class (because it logically belongs there), while indicating that it does not require access to the 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With