如何在NamedTuple上重载`+`

时间:2017-06-19 15:56:42

标签: python mypy

如何在3.5中为命名元组创建加号的自定义重载?我知道3.6中有一些新的语法,你能用3.5做吗?我也想通过mypy检查。

from typing import NamedTuple


Point = NamedTuple('Point',[('x',int),
                            ('y',int)])

def joinPoints(a: Point, b:Point) -> Point:
    return Point(x = a.x+b.x,y=a.y+b.y)

q = Point(1,2)
r = Point(3,4)
s= joinPoints(q,r)
t = q+r #HOW DO I MAKE THIS GO?
#s should equal t

1 个答案:

答案 0 :(得分:1)

作为一个注释,用于在Python 3.6中定义类型化的名称元素的新的基于类的语法最终在运行时做的基本上是一堆元编程的hijinkery来创建一个自定义类,它恰好也包含你的自定义{{1方法,如果你包括一个。

由于我们在Python 3.5中没有这种语法,所以你真正做的最好就是自己实现所有的样板,我担心。

请记住,namedtuples基本上是一种定义简单类(子类元组)的便捷方式,仅此而已。如果你想要更复杂的东西,你实际上需要自己实现它。

在任何情况下,完全放弃类型,没有一种超级干净的方式来完成你在运行时上做的事情,更不用说类型了(至少是最好的)我的知识)。我想有一种干净的方法是在定义Point类之后手动修补它,如下所示:

__add__

然而,你必须放弃使用mypy然后 - mypy简化(通常是合理的)假设类的属性和类型签名在定义该类之后不会改变,因此将禁止分配一个新的Point方法,因此会在最后一行抛出错误。

也许有一些更聪明的方法(可能以某种方式使用abc模块?)最终满足你,Python运行时和mypy,但我目前还没有意识到这种方法。