我如何重载'+'上NamedTuple

问题描述:

如何创建加在3.5命名元组自定义超载?我知道3.6中有一些新的语法,你能在3.5中做到吗?我希望它也能通过mypy检查。我如何重载'+'上NamedTuple

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 
+3

你指的是什么新的语法?你需要继承namedtuple和覆盖'__add__' –

+3

你必须创建一个子类来定义'__add__' – theWanderer4865

+0

我不想一个子类,我想特质/基于类型的调度,如函数式语言:/ – Carbon

作为一个说明,什么在Python 3.6定义类型namedtuples新的,基于类的语法最终做在运行时基本上是一帮元编程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使得简化(并且通常是合理的)假设类的属性和类型签名在该类定义后不会改变,因此将不允许将新方法分配给Point,并因此将在最后一行上引发错误。

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