现在的位置: 主页 > 主打产品 > 文章列表

python super()和classmethod

作者:沈阳市沈河区金瑞龙美术社 来源:www.jrlgg.com 发布时间:2017-09-07 13:29:44
 

python super()和classmethod

python super()和classmethod,@(python)。

super(type, obj)

子类中定义了同父类同名的函数后,需要显示调用父类函数时,可以通过 super,也可以直接通过父类名,建议使用 super,比如在初始化函数中调用父类初始化方法,尤其在多重继承的情况下
看看例子:

#!/usr/bin/env python # coding=utf-8 class A: def __init__(self): print("Enter A") super(A, self).__init__() print("Leave A") class B: def __init__(self): print("Enter B") #super(B, self).__init__() print("Leave B") class CA(A): def __init__(self): print("Enter CA") super(CA,self).__init__() print("Leave CA") class CAA(CA, A): def __init__(self): print("Enter CAA") super(CAA,self).__init__() print("Leave CAA") class CB(B): def __init__(self): print("Enter CB") B.__init__(self) print("Leave CB") class CBB(CB, B): def __init__(self): print("Enter CBB") CB.__init__(self) B.__init__(self) print("Leave CBB") if __name__ == "__main__": print("- New Object CAA") caa = CAA() print("- New Object CBB") cbb = CBB()

上述列子中,两组类关系:
CAA->CA->A 采用 super 调用父类函数
CBB->CB->B 直接通过父类名调用其行数

对比运行结果

lcd@ubuntu:~/learn/python$ python3 supper_class.py - New Object CAA Enter CAA Enter CA Enter A Leave A Leave CA Leave CAA - New Object CBB Enter CBB Enter CB Enter B Leave B Leave CB Enter B -->重复调用了 Leave B Leave CBB

可以看到,使用super, python 不止保证继承时按顺序调用父类初始化,而且保证每一个类不被重复调用。

classsmethod

python 有三种方式定义类方法:
如下面例子类 A 定义的三个方法,
* 常规方式定义了 foo,同对象实例绑定,通过对象调用的时候,会通过隐式 self 参数传递类对象实例子;如果直接通过类调用,需要显示传递类实例;
* @classmethod 方式定义了 class_foo 方法,同类绑定,可以直接通过类名可以直接调用,调用时通过 cls 隐式参数传递类对象。
* @staticmethod 方式定义的方法和普通函数一样,没有绑定对象,没有传递隐式参,可以通过类实例或者类调用。(属于类的函数,但是不需要访问类,通过后续子类覆盖,更好地组织代码)

#!/usr/bin/env python # coding=utf-8 # by orientlu class A(object): def __init__(self): print("A init") super().__init__() def foo(self, x): '''绑定对象''' print("A exec foo (%s, %d)" %(self, x)) @classmethod def class_foo(cls, x): '''绑定类''' print("exec class_foo (%s, %d)" %(cls, x)) @staticmethod def static_foo(x): '''没有绑定类,对象''' print("exec static_foo (%d)" %(x)) class B(object): def foo(self, x): '''绑定对象''' print("exec foo (%s, %d)" %(self, x)) @classmethod def test_class_foo(cls, x): '''绑定类''' print("exec test_class_foo -2- (%s, %d)" %(cls, x)) def test_class_foo(self, x): '''后面方法覆盖前面的同名方法''' print("exec test_class_foo -1- (%s, %d)" %(self, x)) class AA(A): def __init__(self): print("AA Int") def foo(self, x): '''覆盖了父类函数''' print("AA exec foo (%s, %d)" %(self, x)) class C(AA): def __init__(self): '''子类定义了方法覆盖了父类,通过super调用到父类函数''' super().__init__() print("C init") def c_fun1(self): '''子类没有定义的函数,直接调用父类函数''' self.foo(1) if __name__ == "__main__": print("***********************************") print("-------") a = A() a.foo(1) a.class_foo(1) a.static_foo(1) print("-------") A.foo(a, 1) A.class_foo(1) A.static_foo(1) print("***********************************") b = B() b.test_class_foo(1) # 以下调用出错,因为classmethod被后面的函数所覆盖了 #B.test_class_foo(1) # 实际存在是后面定义的函数 B.test_class_foo(b, 1) print("***********************************") c = C() c.c_fun1()

上述代码在 python3 环境下运行的输出 :

*********************************** ------- A init A exec foo (<__main__.A object at 0x7f6af4c36ac8>, 1) exec class_foo (, 1) exec static_foo (1) ------- A exec foo (<__main__.A object at 0x7f6af4c36ac8>, 1) exec class_foo (, 1) exec static_foo (1) *********************************** exec test_class_foo -1- (<__main__.B object at 0x7f6af4c36b38>, 1) exec test_class_foo -1- (<__main__.B object at 0x7f6af4c36b38>, 1) *********************************** AA Int C init AA exec foo (<__main__.C object at 0x7f6af4c36b70>, 1)

企业建站2800元起,携手武汉肥猫科技,做一个有见地的颜值派!更多优惠请戳:湖北SEO http://hubei.raoyu.net

  • 上一篇:【Web API系列教程】2.2 — ASP.NET Web API中的路由
  • 下一篇:最后一页
  •