Python 普通方法和staticmethod与classmethod的区别

不说废话直接Show me the code,整理来源:http://stackoverflow.com/questions/136097/what-is-the-difference-between-staticmethod-and-classmethod-in-python

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()

先看看常规调用方法时打印出self,发现是一个指向内存的对象

a.foo(1)
# executing foo(<__main__.A object at 0xb7dbef0c>,1)

With classmethods, 打印显示的是A的class类型

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

我们也可以通过A.class_foo()来直接调用类方法,但是通过A.foo()这样的调用会引起TypeError.

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

classmethods 的一种使用方式是利用描述符的功能去实现可继承可变的构造函数 inheritable alternative constructors.

With static methods, 既不需要class参数也不需要self,可以通过以下两种方式进行调用

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

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

foo只是一个方法, 但是调用a.foo 的时候不是仅仅的得到了这个方法,我们得到了这个对象 a 的foo方法的"partially applied" ,对象a默认绑定到这个方法的第一个参数 ,方法foo 指定了两个参数,但是 a.foo实际只需要开发者传入一个参数. 我们来对方法进行打印来进一步看看里面的奥妙.

对象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'>>

staticmethod 就更直接,什么也不绑定

print(a.static_foo)
# <function static_foo at 0xb7d479cc>

通过类调用也是一样的.

print(A.static_foo)
# <function static_foo at 0xb7d479cc>

推荐阅读更多精彩内容