python中3种方式定义类方法,常规方式、@classmethod修饰方式、@staticmethod修饰方式。
class?A(object): ????def?foo(self,?x): ????????print('调用foo函数?(%s,?%s)'%(self,?x)) ????????print('self:',?self) ????@classmethod ????def?class_foo(cls,?x): ????????print('调用class_foo函数?(%s,?%s)'?%?(cls,?x)) ????????print('cls:',?cls) ????@staticmethod ????def?static_foo(x): ????????print('调用static_foo函数?(%s)'?%?(x)) a?=?A()
1. 定义方式
普通foo()函数需要self参数隐式的传递当前类对象的实例。@classmethod修饰的方法class_foo()需要通过cls参数传递当前类对象。@staticmethod修饰的方法定义与普通函数是一样的。
self和cls的区别不是强制的,只是PEP8中一种编程风格,slef通常用作实例方法的第一参数,cls通常用作类方法的第一参数。即通过self来传递当前类对象的实例,cls传递当前类对象。
2. 绑定对象
foo方法绑定对象A的实例 print(a.foo) <bound?method?A.foo?of?<__main__.A?object?at?0x100721cf8>> class_foo方法绑定对象A print(a.class_foo) <bound?method?A.class_foo?of?<class?'__main__.A'>> static_foo没有参数绑定。 print(a.static_foo) <function?A.static_foo?at?0x100727730>
3. 调用的方式
foo可通过实例a调用,类对象A直接调用会参数错误。
print(a.foo(1)) 调用foo函数?(<__main__.A?object?at?0x10245ccf8>,?1) self:?<__main__.A?object?at?0x10245ccf8> print(A.foo(1)) Traceback?(most?recent?call?last): ??File?"/Users/liuhuiling/Desktop/MT_code/OPUnittest/case/demo.py",?line?63,?in?<module> ????print(A.foo(1)) TypeError:?foo()?missing?1?required?positional?argument:?'x'
class_foo可通过类对象A 或对象实例a调用。
a.class_foo(2) A.class_foo(2) 调用class_foo函数?(<class?'__main__.A'>,?2) cls:?<class?'__main__.A'>
static_foo可通过类对象A 或对象实例a调用。
a?=?A() a.static_foo(3) A.static_foo(3) 调用static_foo函数?(3)
4. 继承与覆盖普通类函数一样。
class?C(A): ????pass c?=?C() c.foo(1) c.class_foo(1) c.static_foo(1)
运行结果:
调用foo函数?(<__main__.B?object?at?0x10246a2b0>,?1) self:?<__main__.B?object?at?0x10246a2b0> 调用class_foo函数?(<class?'__main__.B'>,?1) cls:?<class?'__main__.B'> 调用static_foo函数?(1)