Skip to content

Latest commit

 

History

History
76 lines (46 loc) · 3.26 KB

305.md

File metadata and controls

76 lines (46 loc) · 3.26 KB

#@staticmethod(静态方法)和@classmethod(类方法)有什么区别?

原问题地址:http://stackoverflow.com/questions/136097/what-is-the-difference-between-staticmethod-and-classmethod-in-python

##问题:

@staticmethod装饰的函数和用 @classmethod装饰的函数有什么区别?

##答案:

也许一些代码示例会有所帮助。注意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。事实上,如果你把某个东西定义为classmethod,可能是因为你打算从类而不是从类的实例中调用它。A.foo(1)可能会引发TypeError,但A.class_foo(1)刚刚好:

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

人们已经发现类方法的一种用途是创建可继承的替代性构造函数(inheritable alternative constructors)

在静态方法中,self(对象实例)和cls(类)都不能作为第一个参数来隐式传递。它们的功能就像普通函数一样,只不过你可以从实例或类来调用它们:

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

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

Staticmethods用来对函数进行分组,这些函数和某个类有着逻辑关联。

foo只是一个函数,但是当你调用a.foo时,你得到的不只是函数本身,你还会得到该函数的一个“局部应用”的版本,并且对象实例被绑定为该函数的第一个参数。foo有2个参数,而a.foo只有1个参数。

下面这个术语“绑定”的意思是说:a被绑定到foo

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

a.class_foo中,被绑定到class_foo的不是a,而是A这个类。

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

尽管这里的staticmethod是一个方法,a.static_foo也只是返回函数,并且这个函数没有绑定的参数。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>

【编者注:另外对静态方法和类方法的比较,可以参考:《零基础学Python(第二版)之类(5)部分》