问题
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:
- You invoke
MyList([1,2,3,4]) - This first invokes
MyList.__new__(MyList,[1,2,3,4]) - Your implementation calls
list.__new__(MyList,[1,2,3,4])This returns a new instance ofMyList, with no elements.list.__new__does not populate the list. It leaves that tolist.__init__, which is never called. - Your
__new__method appends'FirstMen'to the emptyMyListinstance. - Your
__new__method returns the instance ofMyList. MyList.__init__([1,2,3,4])is invoked.- It sets the
nameattribute to'Westeros'. - It returns.
- The instance is assigned to
my_listand 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