python语法之继承

1.缩进。

要么使用tab,要么使用空格,在一个结构内,必须保持一致,否则会提示错误。

2.继承。

如果被继承的父类和子类不在同一个文件,子类中除了import父类之外,还需要以<父类文件名>.< 父类名>这种格式使用父类。否则,就不能继承父类,而是默认继承最原始的metaclass。

3.子类和父类同名成员的调用。

子类会继承父类的成员变量和成员方法。通过self即可获得这些成员的引用,前提是子类并没有重新定义这些成员。如果子类重新定义了成员,则通过self得到的是子类成员。

3.A继承B,调用super方法。

A调用super方法时,要这么写:super(A,self).XXX(XX).即要告诉B,是A继承了你。

4.新式类,经典类。

新式类是A(object)的定义方式,经典类是A()的定义方式。在多继承方面,经典类是从左到右,深度优先。新式类是广度优先,从左到右。

深度优先,从左到右的例子:

object
  |       \
  |        A
  |      / |
  B  C  D
   \   /   |
     E    |
       \   |
         F

所以,MRO是FEBCDAObject

5.多继承。

①通过super调用__init__

被继承的类需要是新式类?是的,如果是通过super来调用__init__,文档中说super() only works for new-style classes。多继承是否正确运行,主要搞清楚各个类__init__方法的调用与否,以及顺序,这些都是MRO来决定的 ,所以用__mro__来查看这些信息对确保多继承正确就很有必要。如果每个类都使用super,super通过自动mro的方式来保证多继承的各个父类的函数被逐一调用,而且保证每个父类函数只调用一次。

使用super,要注意继承列表的顺序。super(TYPE, self).method调用的是mro列表中第一个,也即继承列表第一个类的方法。

所以,一般通过super调用父类的__init__ 方法就可以了,这样保证所有构造方法都执行一次,且是等依次进入,依次离开,比如enter b,enter a,leave a,leave b(栈结构,最后进入的构造器最先执行完毕)。

聪明的小伙伴都会利用打印各个类构造方法的进入和离开,以及__mro__来得到构造器调用顺序,并且针对性来编码,不过这也是被大家所诟病的一点,太麻烦,容易错。

②通过父类名调用__init__

新式类并不必须使用super直接调用被继承类__init__作为unbound方法调用,需要指定一个实例,如self作为参数,依次调用各个被继承类。缺点是若果这几个被继承类也在构造方法里面使用这样调用了同一个上级被继承类,会出现“爷爷类”的构造方法被调用多次的情况。不过呢,仍然是依据MRO来执行各个构造方法,只是有爷爷类构造方法的冗余。比如C(A),D(A),F(C,D),则A会冗余。

4⃣️super和父类名混用。

混用super类和非绑定的函数是一个危险行为,这可能导致应该调用的父类函数没有调用或者一个父类函数被调用多次。一般来说,当父类有两个以上时,如果混用了super和显示地通过父类名调用父类的__init__方法,就可能会出现某些构造方法多次调用或不调用的混乱。根据所谓的深度优先,就是当本来应该执行A构造,但是若A还有一个子类C被继承了,且执行了C.__init__,那就会先跑C,再去跑A,再根据所谓的从左到右,就是先假定右边不存在,先满足左边,然后再假定左边不存在。

使用Composition / Association Pattern的设计模式(即'Is-A'转换成'Has-A')来实现相同功能,避免多重继承。

这个方法听起来未免有点让人不快(破坏了原有设计思维),但实际上很可能这是更好的方式,更清晰的代码,尤其是要继承的类里面混合了使用super__init__两种初始化方式的时候。


以上内容主要参考:

http://blog.ptsang.net/constructors_with_different_arguments_in_python_multiinheri_class

http://www.pythontab.com/html/2013/pythonhexinbiancheng_0828/550.html




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值