开发者

Are there any benefits from using a @staticmethod?

开发者 https://www.devze.com 2023-03-23 10:35 出处:网络
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.

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 
0

精彩评论

暂无评论...
验证码 换一张
取 消