【问题标题】:Python: Inheriting from Built-In TypesPython:从内置类型继承
【发布时间】:2009-05-26 15:43:52
【问题描述】:

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

让我给你一个具体的例子。我经常使用图表,即与边相连的节点。我开始在自己的图形框架上做一些工作。

有一个类Edge,它有自己的属性和方法。它还应该从类 GraphElement 继承。 (GraphElement 是在特定图的上下文之外没有任何意义的每个对象。)但在最基本的层面上,边只是包含两个节点的元组。如果您可以执行以下操作,那将是很好的语法糖:

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

所以 (u,v) 将包含“Spam”和“Eggs”。它还支持像

这样的迭代
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 个)。我做错了什么?

【问题讨论】:

    标签: python oop graph


    【解决方案1】:

    由于元组是不可变的,您还需要重写 __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)
    

    【讨论】:

      【解决方案2】:

      根据您的需要,我会避免多重继承并使用生成器实现迭代器:

      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
      

      【讨论】:

      • 我明白了。那确实会给我我想要的所有语法细节。这似乎是更好的解决方案,谢谢。
      【解决方案3】:

      您需要覆盖 __new__ -- 目前 tuple.__new__ 正在被调用(因为您没有覆盖它),其中包含您传递给 Edge 的所有参数。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-08-28
        • 2019-07-20
        • 2010-12-12
        • 1970-01-01
        • 2015-11-14
        • 2010-09-22
        • 1970-01-01
        相关资源
        最近更新 更多