用@staticmethod修饰的函数和用@staticmethod修饰的函数有@staticmethod @classmethod ?
也许一些示例代码会有所帮助:注意foo , class_foo和static_foo的调用签名的static_foo :
class A(object):
def foo(self,x):
print "executing foo(%s,%s)"%(self,x)
@classmethod
def class_foo(cls,x):
print "executing class_foo(%s,%s)"%(cls,x)
@staticmethod
def static_foo(x):
print "executing static_foo(%s)"%x
a=A()下面是对象实例调用方法的常用方法。对象实例a隐式传递为第一个参数。
a.foo(1)
# executing foo(<__main__.A object at 0xb7dbef0c>,1) 使用 classmethods ,对象实例的类隐式传递为第一个参数而不是self 。
a.class_foo(1)
# executing class_foo(<class '__main__.A'>,1)您也可以使用该类调用class_foo 。实际上,如果您将某些东西定义为类方法,那可能是因为您打算从类而不是类实例中调用它。 A.foo(1)会引发一个 TypeError,但是A.class_foo(1)工作正常:
A.class_foo(1)
# executing class_foo(<class '__main__.A'>,1)人们发现类方法的一个用途是创建可继承的替代构造函数 。
对于 staticmethods , self (对象实例)和cls (类)都不会作为第一个参数隐式传递。它们的行为类似于普通函数,除了您可以从实例或类中调用它们:
a.static_foo(1)
# executing static_foo(1)
A.static_foo('hi')
# executing static_foo(hi)Staticmethod 用于将与类有逻辑连接的函数分组到类中。
foo仅仅是一个函数,但是当你调用a.foo你不只是得到的功能,你会得到一个 “部分应用” 功能与对象实例的版本a绑定作为第一个参数的函数。 foo需要 2 个参数,而a.foo只需要 1 个参数。
a是foo 。这就是下面的 “绑定” 一词的含义:
print(a.foo)
# <bound method A.foo of <__main__.A object at 0xb7d52f0c>>使用a.class_foo , a不绑定到class_foo ,而是将类A绑定到class_foo 。
print(a.class_foo)
# <bound method type.class_foo of <class '__main__.A'>>在这里,使用a.static_foo方法,即使它是一个方法, a.static_foo只返回一个没有参数绑定的良好'ole 函数。 static_foo需要 1 个参数,而a.static_foo需要 1 个参数。
print(a.static_foo)
# <function static_foo at 0xb7d479cc>当然,当你用类A调用static_foo时会发生同样的事情。
print(A.static_foo)
# <function static_foo at 0xb7d479cc>
staticmethod是一种对调用它的类或实例一无所知的方法。它只是获取传递的参数,没有隐含的第一个参数。它在 Python 中基本没用 - 您可以使用模块函数而不是静态方法。
甲类方法 ,在另一方面,是获取传递的类,它被称为上,或该类的实例,它被称为上的,作为第一个参数的方法。当您希望该方法成为该类的工厂时,这很有用:因为它获取了作为第一个参数调用的实际类,所以即使涉及子类,也可以始终实例化正确的类。例如,观察dict.fromkeys()在子类上调用时如何返回子类的实例:
>>> class DictSubclass(dict):
... def __repr__(self):
... return "DictSubclass"
...
>>> dict.fromkeys("abc")
{'a': None, 'c': None, 'b': None}
>>> DictSubclass.fromkeys("abc")
DictSubclass
>>>
基本上@classmethod创建了一个方法,其第一个参数是从中调用的类(而不是类实例), @staticmethod没有任何隐式参数。