gpt4 book ai didi

python - 根据 David Beazley 的一些代码了解多重继承和 super

转载 作者:太空宇宙 更新时间:2023-11-03 14:58:21 25 4
gpt4 key购买 nike

我观看了screencast来自 David Beazly,他使用多重或更具体的菱形继承(钻石问题)来实现类型检查。我认为他的方法看起来真的很酷,但这也让我感到困惑,我根本不明白它是如何工作的。这是我正在谈论的代码:

class Contract:
@classmethod
def check(cls, value):
pass


class Integer(Contract):
@classmethod
def check(cls, value):
assert isinstance(value, int), 'Expected int'
super().check(value)


class Positive(Contract):
@classmethod
def check(cls, value):
assert value > 0, 'Must be > 0'
super().check(value)


class PositiveInteger(Positive, Integer):
pass

它正在发挥作用:

>>> PositiveInteger.check(-3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in check
AssertionError: Must be > 0
>>> PositiveInteger.check(4.88)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in check
File "<stdin>", line 4, in check
AssertionError: Expected int

我的问题是:

  1. 为什么需要定义带有方法检查的基类 Contract 才能使其工作?

  2. 我对 super 的作用有基本的了解。我知道它可以让我们避免显式调用基类并以某种方式处理多重继承。但在这个例子中它到底做了什么?

最佳答案

让我们像调试器一样逐行浏览它。

PositiveInteger.check(x)

# Method resolution order:
# PositiveInteger, Positive, Integer, Contract (from Positive), Contract (from Integer)

# Look through MRO for .check() method. Found in Positive.

assert x > 0
super().check(value)

# super() checks for next .check() method in MRO. Found in Integer

assert isinstance(x, int)
super().check(value)

# super() checks for next .check() method in MRO. Found in Contract

pass

要轻松查找方法解析顺序,请使用 inspect.getmro() .

如果您显式使用了基类,则在 Positive 之后,基类是 Contract,因此永远不会调用 Integer

当你调用最后一个super()时,你需要在Contract中定义.check(),如果Contract 没有 .check() 方法,它会引发 AttributeError,因为 super() 不会已经找到了。

关于python - 根据 David Beazley 的一些代码了解多重继承和 super,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45337436/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com