Python:我如何从内置列表类型继承?

时间:2012-02-24 14:50:44

标签: python list inheritance new-operator

我想为内置list类型添加一些属性,所以我写了这个:

class MyList(list):
    def __new__(cls, *args, **kwargs):
        obj = super(MyList, cls).__new__(cls, *args, **kwargs)
        obj.append('FirstMen')
        return obj

    def __init__(self, *args, **kwargs):
        self.name = 'Westeros'

    def king(self):
        print 'IronThrone'

if __name__ == '__main__':
    my_list = MyList([1, 2, 3, 4])
    print my_list

my_list仅包含元素'FirstMen'。为什么我的__new__在这里不起作用?我应该如何继承像list这样的内置类型?对于像str这样的不可变类型是否相同?

2 个答案:

答案 0 :(得分:23)

list类型通常在其__init__()方法中对列表进行实际初始化,因为它是可变类型的约定。在对不可变类型进行子类型化时,只需要覆盖__new__()。虽然在子类化列表时可以覆盖__new__(),但对于您的用例没有太大意义。覆盖__init__()

更容易
class MyList(list):
    def __init__(self, *args):
        list.__init__(self, *args)
        self.append('FirstMen')
        self.name = 'Westeros'

另请注意,我建议不要在这种情况下使用super()。您想在此处拨打list.__init__(),而不是其他任何内容。

答案 1 :(得分:8)

首先,您是否将此作为练习来理解__new__?如果没有,几乎可以肯定有更好的方法来做你想做的事情。你能解释一下你想在这里实现的目标吗?

那就是说,这是你的例子中发生的事情:

  1. 您调用MyList([1,2,3,4])
  2. 首先调用MyList.__new__(MyList,[1,2,3,4])
  3. 您的实施电话list.__new__(MyList,[1,2,3,4]) 这将返回MyList的新实例,没有任何元素。 list.__new__未填充列表。它留给list.__init__,永远不会被调用。
  4. 您的__new__方法将'FirstMen'附加到空MyList个实例。
  5. 您的__new__方法会返回MyList
  6. 的实例
  7. MyList.__init__([1,2,3,4])被调用。
  8. 它将name属性设置为'Westeros'
  9. 它返回。
  10. 该实例已分配到my_list并已打印。
  11. 请点击此处查看__new__http://docs.python.org/reference/datamodel.html#basic-customization

    的说明