Python 界面如何工作(在 Twisted 中)?

How does Python interface work (in Twisted)?

我正在关注这个 explanation,但我不太明白 Python 解释器是如何得出以下结果的。在第一个例子中,Python 看到 @implementer(IAmericanSocket) 没有被 UKSocket 实现,然后它决定把它变成 AdaptToAmericanSocket 因为那是 [=16= 的唯一实现] 用一个参数?如果有另一个 class 实例用一个参数实现 IAmericanSocket 怎么办?在第二个例子中,为什么 IAmericanSocket 没有覆盖 AmericanSocket 的电压方法?

>>> IAmericanSocket(uk)
<__main__.AdaptToAmericanSocket instance at 0x1a5120>
>>> IAmericanSocket(am)
<__main__.AmericanSocket instance at 0x36bff0>

使用以下代码:

from zope.interface import Interface, implementer
from twisted.python import components

class IAmericanSocket(Interface):
    def voltage():
      """
      Return the voltage produced by this socket object, as an integer.
      """

@implementer(IAmericanSocket)
class AmericanSocket:
    def voltage(self):
        return 120

class UKSocket:
    def voltage(self):
        return 240

@implementer(IAmericanSocket)
class AdaptToAmericanSocket:
    def __init__(self, original):
        self.original = original

    def voltage(self):
        return self.original.voltage() / 2

components.registerAdapter(
    AdaptToAmericanSocket,
    UKSocket,
    IAmericanSocket)

您可以在此处查看 zope.interface 的完整文档:http://docs.zope.org/zope.interface/ - 它可能提供比 Twisted 的快速教程更全面的介绍。

为了回答您的具体问题,最后的 registerAdapter 调用改变了调用 IAmericanSocket 的行为。

当您调用 Interface 时,它首先检查它的参数 是否提供 本身。由于 class AmericanSocket 实现 IAmericanSocketAmericanSocket 的实例提供 IAmericanSocket.这意味着当您使用 AmericanSocket 实例的参数调用 IAmercianSocket 时,您只需取回该实例。

然而,当参数尚未提供接口时,接口会搜索 适配器,它可以转换参数 提供的东西 提供给目标接口。 ("Searches for adapters" 是一个巨大的过度简化,但 Twisted 的 registerAdapter 专门用于允许这种类型的简化。)

因此,当使用 UKSocket 的实例调用 IAmericanSocket 时,它会从 UKSocket 的实例中找到已注册的适配器。适配器本身是一个 1-argument 可调用函数,它接受一个被适配类型的参数 "from" (UKSocket) 和 returns 一个被适配类型的值 "to" (provider IAmericanSocket)。 AdaptToAmericanSocket 是一个 class,但是 classes 本身是可调用的,并且由于它的构造函数采用 UKSocket,它符合 thing-that-takes-1-argument 的契约-of-type-UKSocket-and-returns-an-IAmericanSocket.

另一个 class 的存在不会有什么不同,除非它被注册为适配器。如果您注册两个可能都适合的适配器,它们的交互会很复杂,但由于它们都可以完成工作,理论上您不应该关心使用哪个。