Python: How can I inherit from the built-in list type?

僤鯓⒐⒋嵵緔 提交于 2019-12-17 18:28:10

问题


I want to add some attributes to the built-in list type, so I wrote this:

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

but my_list contains only the element 'FirstMen'. Why my __new__ doesn't work here? And how should I inherit from a built-in type like list? Is it the same for the immutable types like str?


回答1:


The list type usually does the actual initialisation of the list inside its __init__() method, as it is the convention for mutable types. You only need to overwrite __new__() when subtyping immutable types. While you can overwrite __new__() when subclassing list, there is not much point in doing so for your use case. It's easier to just overwrite __init__():

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

Also note that I recommend against using super() in this case. You want to call list.__init__() here, and not possibly anything else.




回答2:


First of all, are you doing this as an exercise to understand __new__? If not, there is almost certainly a better way to do what you're trying to do. Could you explain what you'd like to achieve here?

That said, here's what's happening in your example:

  1. You invoke MyList([1,2,3,4])
  2. This first invokes MyList.__new__(MyList,[1,2,3,4])
  3. Your implementation calls list.__new__(MyList,[1,2,3,4]) This returns a new instance of MyList, with no elements. list.__new__ does not populate the list. It leaves that to list.__init__, which is never called.
  4. Your __new__ method appends 'FirstMen' to the empty MyList instance.
  5. Your __new__ method returns the instance of MyList.
  6. MyList.__init__([1,2,3,4]) is invoked.
  7. It sets the name attribute to 'Westeros'.
  8. It returns.
  9. The instance is assigned to my_list and printed.

See here for an explanation of __new__: http://docs.python.org/reference/datamodel.html#basic-customization



来源:https://stackoverflow.com/questions/9432719/python-how-can-i-inherit-from-the-built-in-list-type

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!