我正在遵循此explanation,但我不太了解Python解释器如何到达以下位置。在第一个示例中,Python是否看到@implementer(IAmericanSocket)不是由UKSocket实现的,所以它决定将其设置为AdaptToAmericanSocket,因为那是IAmericanSocket仅有一个参数的实现?如果还有另一个类实例使用一个参数实现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时,它首先检查其参数是否提供自身。由于类AmericanSocket实现IAmericanSocket,因此AmericanSocket的实例提供IAmericanSocket。这意味着,当您使用IAmercianSocket实例的参数调用AmericanSocket时,只需将实例取回即可。

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

因此,当使用IAmericanSocket的实例调用UKSocket时,它将从UKSocket的实例中找到已注册的适配器。适配器本身是1个参数的可调用对象,它接受类型为“ from”(UKSocket)的类型的参数,并返回类型为“ to”(IAmericanSocket的提供者)的值。 AdaptToAmericanSocket是一个类,但是类本身是可调用的,并且由于其构造函数采用了UKSocket,因此它适合事物-需要1参数类型-UKSocket并返回的契约。 an- IAmericanSocket

除非已将另一个类注册为适配器,否则其他类的存在不会有所不同。如果您注册了两个可能都适合的适配器,则它们的交互会很复杂,但是由于它们都能完成工作,因此从理论上讲,您不必在意使用哪个适配器。

关于python - Python界面如何工作(在Twisted中)?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31713257/

10-09 10:16