【问题标题】:How is this execute function referenced in this code?此代码中如何引用此执行函数?
【发布时间】:2018-03-08 09:54:15
【问题描述】:

我是一名刚接触 Python 的 Java 程序员。我无法理解来自 GitHub 中 pymodbus 存储库的以下代码的语法。函数定义在哪里?

self.execute(request)

我感到困惑的原因是 AFAIK self 指的是当前类的变量和函数,甚至是继承的。 ModBusClientMixIn 类中没有定义函数,该类也没有从任何其他类继承。那么它是从哪里来的呢?

ReadCoilsRequest 类中定义了一个execute 函数,但是要调用它,为什么需要self?另外,上下文(执行函数参数列表中的变量)来自哪里?

如果有人能帮助我理解语法,我将不胜感激。

【问题讨论】:

标签: python design-patterns syntax mixins


【解决方案1】:

这是一个mixin,用于确实定义execute方法的类,例如:

class ModbusClientProtocol(protocol.Protocol, ModbusClientMixin):

mixin 将方法添加到其他类,不应单独使用。

如果你想正确地对它进行类型注释,它必须是这样的:

class Executable(ABC):
    @abstractmethod
    def execute(self):
        pass

class ModBusClientMixin:
    def read_coils(self: Executable, address, count=1, **kwargs):
        #          ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
        # Expects self to conform to Executable interface,
        # i.e. to be used in a class that implements execute().
        self.execute()

由于 Python 严重依赖鸭子类型并且类型注释是相对较新的添加,因此它们经常被省略并被冗长的文档所取代,或者期望开发人员认识到 mixins 的用途,或者它是这样的内部实现没有明确记录的细节。

【讨论】:

  • 所以从你的帖子中我可以理解的是。在 ModBusClientProtocol 中定义了 execute 方法,ModBusClientProtocol 类实际上是在定义时将方法添加到 ModBusClientMixin 类中的。这对我来说很奇怪,我正在从另一个从未见过的类中修改特定类的行为。
  • 我对如何声明方法的理解是否正确?
  • 那么上下文变量来自哪里?
  • Python 允许多重继承,因此一个类可以从多个父类继承方法。 ModBusClientMixin 被用作这样的父级之一,其目的很可能主要是在不强制执行强大的类层次结构的情况下减少代码重复。在其他语言中,你有这样的东西作为 trait。很简单,最终ModbusClientProtocolprotocol.ProtocolModbusClientMixin 的合并,结合了两个类的方法并添加了自己的方法。
  • 就像我在另一个答案的评论中提到的那样 - 执行是否像 java 的抽象方法?
【解决方案2】:

这是一种特殊情况。没错,execute 必须在某个地方定义。

但在这种情况下,execute 是由派生自 ModBusClientMixInchild 类实现的。

如果您要直接创建ModBusClientMixIn 的实例,则会出现错误,因为它没有实现execute

例如,查看ModbusClientProtocolBaseModbusClient 的实现,它们都有一个execute 方法。

【讨论】:

  • 是的,所以它就像 Java 中的抽象方法,对吧?
猜你喜欢
  • 2011-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-28
  • 2014-02-17
  • 1970-01-01
  • 2019-06-12
  • 2015-07-12
相关资源
最近更新 更多