Python接口如何工作(在Twisted中)?

Python接口如何工作(在Twisted中)?,python,interface,twisted,Python,Interface,Twisted,我正在关注这一点,我不太明白Python解释器是如何得出以下结论的。在第一个示例中,Python是否看到@implementer(IAmericanSocket)不是由UKSocket实现的,然后它决定将其设置为adaptetoAmericanSocket,因为这是IAmericanSocket的唯一一个带有一个参数的实现?如果有另一个类实例使用一个参数实现IAmericanSocket,该怎么办?在第二个示例中,为什么IAmericanSocket没有覆盖AmericanSocket的电压方法

我正在关注这一点,我不太明白Python解释器是如何得出以下结论的。在第一个示例中,Python是否看到
@implementer(IAmericanSocket)
不是由
UKSocket
实现的,然后它决定将其设置为
adaptetoAmericanSocket
,因为这是
IAmericanSocket
的唯一一个带有一个参数的实现?如果有另一个类实例使用一个参数实现
IAmericanSocket
,该怎么办?在第二个示例中,为什么
IAmericanSocket
没有覆盖
AmericanSocket
的电压方法

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

您可以在这里看到zope.interface的完整文档:-它可能提供比Twisted的快速教程更全面的介绍

为了回答您的特定问题,此处末尾的
registerAdapter
调用会更改调用
IAmericanSocket
的行为

调用
接口时,它首先检查其参数是否提供自身。由于类
AmericanSocket
实现了
IAmericanSocket
,因此
AmericanSocket
的实例提供了
IAmericanSocket
。这意味着当您使用
AmericanSocket
实例的参数调用
IAmercianSocket
时,您只需返回该实例

但是,当参数尚未提供接口时,接口会搜索适配器,这些适配器可以将参数提供的内容转换为目标接口。(“搜索适配器”是一个巨大的过度简化,但是Twisted的
registerAdapter
专门允许这种简化。)

因此,当使用
UKSocket
的实例调用
IAmericanSocket
时,它会从
UKSocket
的实例中找到已注册的适配器。适配器本身是一个可调用的单参数,它接受“从”(
UKSocket
)调整的类型的参数,并返回“到”(IAmericanSocket的提供程序)调整的类型的值
AdapteToAmericanSocket
是一个类,但类本身是可调用的,由于其构造函数采用了
UKSocket
,因此它符合thing-that-takes-1-argument-of-type-
UKSocket
,并返回一个-
IAmericanSocket

另一个类的存在不会产生任何影响,除非它注册为适配器。如果您注册了两个可能都适用的适配器,那么它们的交互是复杂的,但是由于它们都可以完成这项工作,理论上您不应该关心使用哪一个

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)