静态方法和类方法之间的区别

2024-04-19 10:30:27 发布

您现在位置:Python中文网/ 问答频道 /正文

^{}修饰的函数和用^{}修饰的函数有什么区别?


Tags: 函数区别
3条回答

基本上,@classmethod生成的方法的第一个参数是它从中调用的类(而不是类实例),@staticmethod没有任何隐式参数。

也许一点示例代码会有所帮助:注意fooclass_foostatic_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)可能会引发类型错误,但A.class_foo(1)工作正常:

A.class_foo(1)
# executing class_foo(<class '__main__.A'>,1)

人们发现类方法的一个用途是创建inheritable alternative constructors


对于staticmethods,无论是self(对象实例)还是cls(类)都不会作为第一个参数隐式传递。它们的行为类似于普通函数,只是您可以从实例或类调用它们:

a.static_foo(1)
# executing static_foo(1)

A.static_foo('hi')
# executing static_foo(hi)

Staticmethods用于将与类有某种逻辑连接的函数分组到该类。


foo只是一个函数,但是当您调用a.foo时,您不只是得到函数, 您将得到函数的“部分应用”版本,对象实例a绑定为函数的第一个参数。foo需要2个参数,而a.foo只需要1个参数。

afoo绑定。这就是下面“绑定”一词的含义:

print(a.foo)
# <bound method A.foo of <__main__.A object at 0xb7d52f0c>>

使用a.class_fooa不绑定到class_foo,而类A绑定到class_foo

print(a.class_foo)
# <bound method type.class_foo of <class '__main__.A'>>

这里,对于staticmethod,即使它是一个方法,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中基本上是无用的——您可以只使用模块函数而不是staticmethod。

另一方面,class method是作为第一个参数传递给它被调用的类或它被调用的实例的类的方法。当您希望方法成为类的工厂时,这很有用:因为它获得了作为第一个参数调用的实际类,所以即使涉及子类,您也始终可以实例化正确的类。例如,观察类方法dict.fromkeys()在对子类调用时如何返回子类的实例:

>>> class DictSubclass(dict):
...     def __repr__(self):
...         return "DictSubclass"
... 
>>> dict.fromkeys("abc")
{'a': None, 'c': None, 'b': None}
>>> DictSubclass.fromkeys("abc")
DictSubclass
>>> 

相关问题 更多 >