我们真的需要python中的@staticmethod装饰器来声明静态方法

Do we really need @staticmethod decorator in python to declare static method

我很好奇为什么我们需要@staticmethod装饰器来声明方法为static。我在读关于Python中静态方法的文章,我知道静态方法不需要实例化类就可以调用。所以我尝试了下面的两个例子,但都是一样的:

1
2
3
4
5
6
7
8
class StatMethod:
  def stat():
    print("without Decorator")

class StatMethod_with_decorator:
  @staticmethod
  def stat():
    print("With Decorator")

如果我直接调用类上的stat()方法,两个方法都会打印/显示以下值:

1
2
3
4
>> StatMethod.stat()
without Decorator
>> StatMethod_with_decorator.stat()
With Decorator


如果您试图从类的实例而不是直接从类调用@staticmethod,则需要使用decorator。

1
2
3
4
5
6
7
8
9
10
class Foo():
    def bar(x):
        return x + 5

>>> f = Foo()
>>> f.bar(4)
Traceback (most recent call last):
  File"<pyshell#7>", line 1, in <module>
    f.bar(4)
TypeError: bar() takes 1 positional argument but 2 were given

现在,如果我声明@staticmethod,那么self参数不会作为第一个参数隐式传递。

1
2
3
4
5
6
7
8
class Foo():
    @staticmethod
    def bar(x):
        return x + 5

>>> f = Foo()
>>> f.bar(4)
9

文档描述了在调用用户定义的方法时完成的一些转换:

Note that the transformation from function object to (unbound or
bound) method object happens each time the attribute is retrieved from
the class or instance. In some cases, a fruitful optimization is to
assign the attribute to a local variable and call that local variable.
Also notice that this transformation only happens for user-defined
functions; other callable objects (and all non-callable objects) are
retrieved without transformation. It is also important to note that
user-defined functions which are attributes of a class instance are
not converted to bound methods; this only happens when the function is
an attribute of the class.

对于标记为StaticMethod的方法,这是不同的:

Static method objects provide a way of defeating the transformation of
function objects to method objects described above. A static method
object is a wrapper around any other object, usually a user-defined
method object. When a static method object is retrieved from a class
or a class instance, the object actually returned is the wrapped
object, which is not subject to any further transformation. Static
method objects are not themselves callable, although the objects they
wrap usually are. Static method objects are created by the built-in
staticmethod() constructor.


如果函数有一些参数,那么调用非静态方法将失败

静态方法没有使用类中的局部变量,但是类方法将