2009-05-26 48 views
2

組み込み型のサブタイプとそのコンストラクタに関する質問があります。私はクラスがタプルとカスタムクラスの両方から継承するようにしたい。Python:組み込み型から継承する

具体的な例を挙げておきます。私は、エッジで結ばれたノードを意味するグラフでたくさん働いています。自分のグラフフレームワークで作業を始めています。

独自の属性とメソッドを持つEdgeクラスがあります。また、クラスGraphElementから継承する必要があります。 (GraphElementは、特定のグラフのコンテキスト外で意味を持たないすべてのオブジェクトです。)しかし、最も基本的なレベルでは、エッジは2つのノードを含む単なるタプルです。あなたは次の操作を行うことができればそれはシンタックスシュガーいいだろう:

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

ので(U、V)「スパム」と「卵」が含まれます。

for node in edge: ... 

私はなぜサブタイプタプル(またはセットのような他の基本タイプ)を望むのか分かりましたら幸いです。だからここ

は私のエッジクラスとそののinitです:

私は
Edge(aGraph, (source, target)) 

私はTypeError例外を取得呼び出す
class Edge(GraphElement, tuple): 

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

:タプルは()かかりせいぜい1引数(2与えられました) 。私は間違って何をしていますか?

答えて

9

タプルは不変なので、__new__メソッドもオーバーライドする必要があります。現在tuple.__new__が呼び出さなっているあなたはEdgeに渡しているすべての引数で(あなたがそれをオーバーライドしないよう) - あなたは__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

参照してください。

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

。それは確かに私が望むすべての構文上の細部を私に与えるだろう。これはより良い解決策、感謝のようです。 –

関連する問題