Reputation: 1431
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.
Upvotes: 30
Views: 13519
Reputation: 1185
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
Upvotes: 3
Reputation: 38500
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.
Upvotes: 22
Reputation: 72241
Both approaches will work, so it's the matter of readability and following conventions.
Upvotes: 2