Python:继承内置类型

时间:2009-05-26 15:43:52

标签: python oop graph

我有一个关于内置类型及其构造函数的子类型的问题。我希望一个类从元组和自定义类继承。

让我举一个具体的例子。我使用图表工作很多,这意味着与边缘连接的节点。我开始在自己的图形框架上做一些工作。

有一个类Edge,它有自己的属性和方法。它还应该继承自GraphElement类。 (GraphElement是在特定图形的上下文之外没有任何意义的每个对象。)但在最基本的级别,边缘只是包含两个节点的元组。如果你能做到以下几点,这将是很好的语法糖:

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

所以(你,v)将包含“垃圾邮件”和“鸡蛋”。它也支持迭代,如

for node in edge: ...

我希望你能明白为什么我想要子类型元组(或其他类似set的基本类型)。

所以这是我的Edge类及其 init

class Edge(GraphElement, tuple):

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

当我打电话

Edge(aGraph, (source, target))

我得到一个TypeError:tuple()最多需要1个参数(给定2个)。我做错了什么?

3 个答案:

答案 0 :(得分: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)

答案 1 :(得分: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

答案 2 :(得分:3)

您需要覆盖__new__ - 当前tuple.__new__被调用(因为您没有覆盖它),并且您传递给Edge的所有参数。