Are there any benefits from using a @staticmethod?
I was wondering if you use @staticmethod decorator in your code.
Personally I don't use it, since it takes more letters to write @staticmethod then self.
The only benefit (which comes to me) from using it may be a better clarity of a code, but since I usually write a method description for sphi开发者_如何学运维nx, I always state whether a method is using object or not.
Or maybe I should start using @staticmethod decorator ?
Whether to use @staticmethod
or not depends on what you want to achieve. Ignoring the decorator because there is more to type is a rather silly reason (no offense!) and indicates that you have not understood the concept of a static method in Python!
Static methods are independent of the class and any class instance. They only use the class scope as a namespace. If you omit the @staticmethod
decorator, you are creating an instance method that cannot be used without constructing an instance.
Here is a very simple class Foo
:
>>> class Foo(object):
... @staticmethod
... def foo():
... print 'foo'
...
... def bar(self):
... print 'bar'
Now, Foo.foo()
is a static method that can be called directly:
>>> Foo.foo()
foo
Foo.bar()
on the other hand is an instance method, that can only be called from instances (objects) of Foo
:
>>> Foo.bar()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unbound method foo() must be called with Foo instance as first argument (got nothing instead)
>>> foo = Foo()
>>> foo.bar()
bar
To answer your question: If you want to define a static method, use @staticmethod
. Otherwise, don't.
If you have a method that does not use self
, and therefore could be written as a static method, ask yourself: Will you ever want to access this function from outside without having an instance? Most of the times, the answer will be: No.
Assume that we want to define abs
method in class Math
, then we have two choices:
class Math():
def abs(n):
if n>0:
return n
else:
return -n
class Math2():
@staticmethod
def abs(n):
if n>0:
return n
else:
return -n
In Python2:
>>> Math.abs(-2)
TypeError: unbound method abs() must be called with Math instance as
first argument (got int instance instead)
>>>Math().abs(-2)
TypeError: abs() takes exactly 1 argument (2 given)
>>> Math2.abs(-2)
2
>>> Math2().abs(-2)
2
python2 automatically takes Math().abs(-2)
as Math().abs(self,-2)
,so that you have to use @staticmethod
.
In Python3
>>>Math.abs(-3)
3
>>>Math().abs(-3)
TypeError: abs() takes 1 positional argument but 2 were given
>>>Math2.abs(-3)
3
>>>Math2().abs(-3)
3
In python3, you can use classname.method()
without static method, but it will raise TypeError when someone tries to use instance.method()
.
@staticmethod
decorator saves you typing and improves readability.
class Example:
@staticmethod
def some_method():
return
is the same as:
class Example:
def some_method():
return
some_method = staticmethod(some_method)
I think you may be confused about what a static method is in Python as the terminology differs from other languages. A regular method is "bound" to the instance (self
), a class method is "bound" to the class (cls
) while a static method is not "bound" at all (and can not access instance nor class attributes.
See:
- http://docs.python.org/library/functions.html#classmethod
- http://docs.python.org/library/functions.html#staticmethod
In addition to the previous answers, from pythons doc @staticmethod :
It can be called either on the class (such as C.f()) or on an instance (such as C().f()). The instance is ignored except for its class.
class Test:
@staticmethod
def Foo():
print('static Foo')
def Bar():
print('static Bar')
Test.foo() # static Foo
Test.bar() # static Bar
obj = Test()
obj.foo() # static Foo ; note that you can call it from class instance
obj.bar() # ERROR
精彩评论