2017-06-19 67 views
0

如何創建加在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

回答

1

作爲一個說明,什麼在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,但我目前還沒有意識到這種方法。