@staticmethod用 装饰的函数和用 装饰的函数有什么区别@classmethod?
也许一些示例代码会有所帮助:注意foo,class_foo和的调用签名的区别static_foo:
foo
class_foo
static_foo
class A(object): def foo(self, x): print(f"executing foo({self}, {x})") @classmethod def class_foo(cls, x): print(f"executing class_foo({cls}, {x})") @staticmethod def static_foo(x): print(f"executing static_foo({x})") a = A()
下面是对象实例调用方法的常用方式。对象实例 ,a作为第一个参数隐式传递。
a
a.foo(1) # executing foo(<__main__.A object at 0xb7dbef0c>, 1)
使用 classmethods,对象实例的类作为第一个参数而不是self.
self
a.class_foo(1) # executing class_foo(<class '__main__.A'>, 1)
您也可以class_foo使用类调用。实际上,如果您将某个东西定义为类方法,那可能是因为您打算从类中调用它,而不是从类实例中调用它。A.foo(1)会引发 TypeError,但A.class_foo(1)工作得很好:
A.foo(1)
A.class_foo(1)
A.class_foo(1) # executing class_foo(<class '__main__.A'>, 1)
人们发现类方法的一种用途是创建可继承的替代构造函数。
使用 staticmethods,self(对象实例)和 cls(类)都不会作为第一个参数隐式传递。它们的行为类似于普通函数,只是您可以从实例或类中调用它们:
cls
a.static_foo(1) # executing static_foo(1) A.static_foo('hi') # executing static_foo(hi)
静态方法用于对与类与类有某种逻辑联系的函数进行分组。
foo只是一个函数,但是当您调用时,您a.foo不仅会获取该函数,还会获得该函数的“部分应用”版本,其中对象实例a绑定为该函数的第一个参数。foo需要 2 个参数,而a.foo只需要 1 个参数。
a.foo
a必然foo。这就是下文“绑定”一词的含义:
print(a.foo) # <bound method A.foo of <__main__.A object at 0xb7d52f0c>>
with a.class_foo,a不是绑定到class_foo,而是类A是绑定到的class_foo。
a.class_foo
A
print(a.class_foo) # <bound method type.class_foo of <class '__main__.A'>>
在这里,使用静态方法,即使它是一个方法,a.static_foo也只是返回一个没有绑定参数的好 ‘ole 函数。static_foo需要 1 个参数,也 a.static_foo需要 1 个参数。
a.static_foo
print(a.static_foo) # <function static_foo at 0xb7d479cc>
当然,当您改为static_foo与班级通话时,也会发生同样的事情A。
print(A.static_foo) # <function static_foo at 0xb7d479cc>