2009-05-26 62 views
2

我有一個關於內置類型及其構造函數的子類型的問題。我想要一個類繼承自元組和自定義類。Python:繼承自Built-In Types

讓我給你具體的例子。我用圖表工作了很多,意味着與邊緣連接的節點。我開始在自己的圖形框架上做一些工作。

有一個類Edge,它有自己的屬性和方法。它也應該繼承自類GraphElement。 (GraphElement是在特定圖的上下文之外沒有意義的每個對象)。但是在最基本的層面上,邊只是包含兩個節點的元組。這將是很好的語法糖,如果你能做到以下幾點:

edge = graph.create_edge("Spam","Eggs") 
(u, v) = edge 

因此(U,V)將包含「垃圾郵件」和「蛋」。它也支持迭代,如

for node in edge: ... 

我希望你明白爲什麼我想要子類型元組(或其他基本類型,如集)。

因此,這裏是我的緣類及其INIT

class Edge(GraphElement, tuple): 

def __init__(self, graph, (source, target)): 
    GraphElement.__init__(self, graph) 
    tuple.__init__((source, target)) 

當我打電話

Edge(aGraph, (source, target)) 

我得到一個類型錯誤:元組()採用最多1參數(2給出) 。我究竟做錯了什麼?

回答

9

由於元組是不可變的,所以您還需要重寫__new__方法。見http://www.python.org/download/releases/2.2.3/descrintro/#__new__

class GraphElement: 
    def __init__(self, graph): 
     pass 

class Edge(GraphElement, tuple): 
    def __new__(cls, graph, (source, target)): 
     return tuple.__new__(cls, (source, target)) 
    def __init__(self, graph, (source, target)): 
     GraphElement.__init__(self, graph) 
3

你需要重寫__new__ - 目前tuple.__new__獲取調用與所有你傳遞到Edge參數(如你不重寫)。

6

對於你需要什麼,我會避免多重繼承和將實施一個迭代器使用發電機:

class GraphElement: 
    def __init__(self, graph): 
     pass 

class Edge(GraphElement): 
    def __init__(self, graph, (source, target)): 
     GraphElement.__init__(self, graph) 
     self.source = source 
     self.target = target 

    def __iter__(self): 
     yield self.source 
     yield self.target 

在這種情況下,這兩種用法只是正常工作:

e = Edge(None, ("Spam","Eggs")) 
(s, t) = e 
print s, t 
for p in e: 
    print p 
+0

我明白了。這確實會給我所有我想要的語法細節。這似乎是更好的解決方案,謝謝。 – 2009-05-26 16:09:17