【发布时间】:2018-08-25 02:37:01
【问题描述】:
有人可以帮我理解 MRO 在 python 中的工作原理吗? 假设我有四个职业——角色、盗贼、敏捷、偷偷摸摸。 Character 是 Thief 的超类,Agile 和 Sneaky 是兄弟姐妹。请在下面查看我的代码和问题
class Character:
def __init__(self, name="", **kwargs):
if not name:
raise ValueError("'name' is required")
self.name = name
for key, value in kwargs.items():
setattr(self, key, value)
class Agile:
agile = True
def __init__(self, agile=True, *args, **kwargs):
super().__init__(*args, **kwargs)
self.agile = agile
class Sneaky:
sneaky = True
def __init__(self, sneaky=True, *args, **kwargs):
super().__init__(*args, **kwargs)
self.sneaky = sneaky
class Thief(Agile, Sneaky, Character):
def pickpocket(self):
return self.sneaky and bool(random.randint(0, 1))
parker = Thief(name="Parker", sneaky=False)
所以,这就是我的想法,如果我理解正确,请告诉我。
由于敏捷在列表中排在首位,所有参数首先发送到敏捷,其中参数将与敏捷参数交叉引用。如果匹配,则将分配该值,然后将没有匹配关键字的所有内容打包在 *kwargs 中并发送到 Sneaky 类(通过 super),在那里会发生同样的事情 - 所有参数都被解包,与 Sneaky 参数交叉引用(这是在设置了偷偷摸摸 = False 时),然后打包在 kwargs 中并发送到 Character。然后 Character inint 方法中的所有内容都将运行并设置所有值(如 name = "Parker")。
我认为 MRO 在回来的路上是如何工作的
既然所有内容都进入了 Character 类,并且 Character init 方法中的所有内容都已运行,现在它必须返回到 Agile 和 Sneaky 类并完成运行它们 init 方法中的所有内容(或它们的 super 下的所有内容)。所以,它会先回到 Sneaky 类并完成它的 init 方法,然后再回到 Agile 类并完成它的其余 init 方法(分别)。
我是否在任何地方都感到困惑?呸。对不起,我知道这很多,但我真的被困在这里,我正在努力清楚地了解 MRO 的工作原理。
谢谢大家。
【问题讨论】:
-
此代码未按发布的方式运行。至少有一个缩进错误,类乱序,……这意味着无法调试您的代码来帮助回答您的问题。
-
@ReblochonMasque 实际上,在这种协作多重继承中使用的 mixin 调用
super是完全合理的。毕竟,任何方法到达Sneaky的唯一途径是来自Agile调用super。 -
@ReblochonMasque 我不知道任何具体的事情,因为它结合了两个独立的想法,这些想法通常很复杂,可以有自己的单独教程。通常,任何用
super解释协作式 MI 的人都会将示例重点放在菱形层次结构上,例如 this one,而任何解释 mixin 的人,例如 this answer,如果超出了基础知识,可能会继续学习以下课程同时是一个mixin和一个ABC,比如collections.abcs… -
@ReblochonMasque 但是这两个概念很好地结合在一起。一个打算与合作层次结构一起使用的mixin,如果它需要覆盖
__init__(或其他任何东西),即使它没有继承任何东西,它也必须super它。 (当然这意味着 mixin 只能与该层次结构一起使用,但这很好;即使没有任何super,您也不会将werkzeug.AcceptMixin与非werkzeug 类一起使用。 -
@ReblochonMasque 实际上,这只是举了一个例子:大多数 werkzeug mixin 方法并没有覆盖任何需要链接的东西,但有些是,比如
ETagResponseMixin.freeze,它们使用super这样做。这意味着ETagResponseMixin只能在最终基类(或至少某个祖先)具有freeze方法的层次结构中使用它可以super,但这很好,因为它不打算在其他任何地方使用.
标签: python super method-resolution-order