需要注意的是,在 Python 3.6 中用于定义类型化命名元组的新的、基于类的语法最终在运行时所做的基本上是一堆元编程 hijinkery 来创建一个自定义类,__add__
如果你包含一个自定义类,它恰好也包含你的自定义方法.
由于我们在 Python 3.5 中无法使用该语法,因此您真正能做的最好的事情就是自己实现所有样板文件,恐怕。
请记住,namedtuples 基本上是一种定义简单类(即子类元组)的便捷方式,仅此而已。如果你想要更复杂的东西,你实际上需要自己实现它。
在任何情况下,完全搁置类型,没有一种超级干净的方式来做你在运行时尝试做的事情,更不用说类型了(至少,据我所知)。我想一种干净的方法是在定义 Point 类之后手动修补它,如下所示:
from typing import NamedTuple
Point = NamedTuple('Point', [('x', int), ('y', int)])
def add(self: Point, other: Point) -> Point:
return Point(self.x + other.x, self.y + other.y)
Point.__add__ = add
a = Point(1, 2)
b = Point(3, 4)
print(a + b) # prints 'Point(4, 6)'
但是,您将不得不放弃使用 mypy —— mypy 做了简化(通常是合理的)假设,即类的属性和类型签名在定义该类后不会改变,因此不允许分配新方法指向,因此将在最后一行抛出错误。
也许有一些更聪明的方法(也许以某种方式使用 abc 模块?)最终让您、Python 运行时和 mypy 满意,但我目前不知道这种方法。