首页 / PYTHON / Python中的一对多继承
Python中的一对多继承
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Python中的一对多继承,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2902字,纯文字阅读大概需要5分钟。
内容图文
![Python中的一对多继承](/upload/InfoBanner/zyjiaocheng/721/939d6c7b48bb46a1825ef529a8bb7a39.jpg)
关于我是否以最佳方式进行某事的问题……
我希望在Python中有一个类层次结构,它看起来(最低限度)如下所示;
class Actor
class Mover(Actor)
class Attacker(Actor)
class Human(Mover, Attacker)
但是我反对这样一个事实,即Actor有一个我想要初始化的属性,来自Mover和Attacker子类中的每一个,如下面所示;
class Actor:
_world = None
def __init__(self, world):
self._world = world
class Mover(Actor):
_speed = 0
def __init__(self, world, speed):
Actor.__init__(self, world)
self._speed = speed
class Attacker(Actor):
_range = 0
def __init__(self, world, range):
Actor.__init__(self, world)
self._range = range
如果我当时采用我的初始方法,并遵循我在使用超类’构造函数方面的常规方法,我显然最终会调用Actor构造函数两次 – 不是问题,但我的程序员感觉到了tingles并说我宁愿做得更干净;
class Human(Mover, Attacker):
def __init__(self, world, speed, range):
Mover.__init__(self, world, speed)
Attacker.__init__(self, world, range)
例如,我只能调用Mover构造函数,只是简单地初始化了Human的_range,但这对我来说是一个更糟糕的方法,因为它复制了攻击者的初始化代码.
就像我说的那样,我知道两次设置_world属性并不是什么大不了的事,但是你可以想象如果在Actor .__ init__中发生了更为密集的事情,这种情况将会令人担忧.任何人都可以建议在Python中实现这个结构的更好的做法吗?
解决方法:
你在这里得到的是diamond inheritance.Python对象模型通过method resolution order算法解决了这个问题,该算法使用C3 linearization;实际上,你所要做的就是使用super并传递** kwargs(在Python 2中,继承自object):
class Actor(object): # in Python 3, class Actor:
_world = None
def __init__(self, world):
self._world = world
class Mover(Actor):
_speed = 0
def __init__(self, speed, **kwargs):
super(Mover, self).__init__(**kwargs) # in Python 3, super().__init__(**kwargs)
self._speed = speed
class Attacker(Actor):
_range = 0
def __init__(self, range, **kwargs):
super(Attacker, self).__init__(**kwargs) # in Python 3, super().__init__(**kwargs)
self._range = range
class Human(Mover, Attacker):
def __init__(self, **kwargs):
super(Human, self).__init__(**kwargs) # in Python 3, super().__init__(**kwargs)
请注意,您现在需要使用kwargs样式构造Human:
human = Human(world=world, range=range, speed=speed)
这里到底发生了什么?如果您对__init__调用进行检测,则会发现(将类重命名为A,B,C,D以简化):
> D .__ init__调用B .__ init__
> B .__ init__调用C .__ init__
> C .__ init__调用A .__ init__
> A .__ init__调用object .__ init__
发生的事情是,在D的实例上调用的super(B,self)知道C在方法解析顺序中是下一个,所以它转到C而不是直接转到A.我们可以通过查看MRO来检查:
>>> D.__mro__
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>)
为了更好地理解,请阅读Python’s super() considered super!
请注意,超级绝对不是魔术;它的作用可以用Python本身近似(这里仅用于super(cls,obj)功能,使用闭包来绕过__getattribute__ circularity):
def super(cls, obj):
mro = type(obj).__mro__
parent = mro[mro.index(cls) + 1]
class proxy(object):
def __getattribute__(self, name):
return getattr(parent, name).__get__(obj)
return proxy()
内容总结
以上是互联网集市为您收集整理的Python中的一对多继承全部内容,希望文章能够帮你解决Python中的一对多继承所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。