Python中3种方式定义类的方法。常规,classmetod,staticmethod
class A(object): def foo(self, x): print("executing foo(%s,%s)" % (self, x)) print('self:', self) @classmethod def class_foo(cls, x): print("executing class_foo(%s,%s)" % (cls, x)) print('cls:', cls) @staticmethod def static_foo(x): print("executing static_foo(%s)" % x) a = A()
从定义上讲:
普通的类方法foo()需要通过self参数隐式的传递当前类对象的实例。
@classmethod修饰的方法class_foo()需要通过cls参数传递当前类对象。
@staticmethod修饰的方法定义与普通函数是一样的。
self和cls的区别不是强制的,只是PEP8中一种编程风格,
slef通常用作实例方法的第一参数,cls通常用作类方法的第一参数。
即通常用self来传递当前类对象的实例,cls传递当前类对象。
从绑定对象来讲:
foo方法绑定对象A的实例,class_foo方法绑定对象A,static_foo没有参数绑定。
foo可以通过实例a调用方法: >>> a.foo(1) foo也可以通过类,来调用方法。但是要求传入实参a A.foo(a, 1)
class_foo通过类对象或对象实例调用。 >>> A.class_foo(1) executing class_foo(<class '__main__.A'>,1) cls: <class '__main__.A'> >>> a.class_foo(1) executing class_foo(<class '__main__.A'>,1) cls: <class '__main__.A'>
static_foo通过类对象或对象实例调用。 >>> A.static_foo(1) executing static_foo(1) >>> a.static_foo(1) executing static_foo(1)
classmethod与staticmethod这两者的区别在于,classmethod增加了一个对实际调用类的引用,这带来了很多方便的地方:
可以判断出自己是通过基类被调用,还是通过某个子类被调用通过子类调用时,
可以返回子类的实例而非基类的实例通过子类调用时,
可以调用子类的其他classmethod