多重方法和多重调度之间有什么区别吗



我想在Python中使用重载。我知道这在设计上是不可能的(Python是动态类型语言(,这里有关于这个主题的很好的线程。这就是为什么我可以使用类似多分派(multimethods(的东西。我正在考虑最好的解决方案,即为任何函数或类方法实现多重调度Python中是否有本机包含的解决方案

在我的情况下,使用singledispatch(在3.4中添加到Python中(是不够的(因为只考虑第一个参数的类型,并且我需要多个(。

我也知道我可以使用关键字参数(即,具有单个函数并通过检查所有参数来驱动行为(,但当你有很多参数和组合时,它会变得复杂。

到目前为止,我能够找到这两个库(不包括在Python标准库中(:

  • multimethod-提供了一个装饰器,用于向函数添加多参数调度,可以使用与functools相同的注册样式。singledispatch可以很好地与注释配合使用,甚至可以与带注释的谓词配合使用,或者为类提供特殊的multimeta命名空间
  • multiplexdispatch-还为多参数调度提供了decorator,不使用注释,与以前的库相比,我觉得功能不那么强大

基本用法如下:

from multimethod import multimethod
@multimethod
def add(x: int, y: int):
...
@multimethod
def add(x: str, y: str):
...

from multipledispatch import dispatch
@dispatch(int, int)
def add(x, y):
...
@dispatch(str, str)
def add(x, y):
...

这个功能看起来非常相似。

我主要有两个问题:

  • 这些多重调度实现中的一个是否比另一个带来了任何(dis(优势(例如,支持的类型、速度、性能、限制等(这似乎是可以比较的,但我对此不确定,因为后者(multiplexdispatch(似乎更受欢迎(检查GitHub星级(,但维护较少(我甚至会说不太成熟(
  • 还有其他解决方案吗(即使是Python标准库中包含的解决方案(

为什么多方法比多调度好得多的原因

  1. 键入我们添加到方法签名中的信息,而不是添加到decorator签名中。这样做是非常直观和干净的
  2. multimethod的类型提示与静态类型support/mypy所期望的相同。现在,类型注释在开发人员中变得很常见。所以,这对双方都有帮助!Multimethod类型提示与mypy类型提示正式相同
  3. 请注意,无论是多方法还是多调度,它们似乎只支持非关键字函数调用。如果调用带有关键字的函数,则两者都会失败。这令人失望,但他们可能有更多的理由这样做。请阅读各自模块的指南。他们谈论基于关键字的函数调用,但不是很清楚,IMO。因此,有时我觉得,在我们的函数中进行简单的类型检查可以同时解决所有问题,而不是使用多方法或多调度。毕竟,我想要第一类解决方案,因为函数是第一类对象
  4. 正如我所知,语言中没有多态性/函数重载的解决方案。但是多方法看起来是Python的和原生的。我很喜欢它。此外,multimethod也支持单一调度,尽管我从未觉得有必要
  5. 谢谢你的提问。你已经回答了。直到我读到你的问题,我才意识到其中的确切区别。你们已经给出了答案。谢谢你的提问

除了接受的答案,我还想添加。。。

  1. multimethod包在签名中使用延迟类型提示非常有效,而multiplexdispatch则不然。例如
@multimethod
def __init__(self, color: "Color"):
self.hex = color.hex

这也适用于from __future__ import annotations,它在引擎盖下做同样的事情。

最新更新