我想为内置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
这样的不可变类型是否相同?
答案 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__
?如果没有,几乎可以肯定有更好的方法来做你想做的事情。你能解释一下你想在这里实现的目标吗?
那就是说,这是你的例子中发生的事情:
MyList([1,2,3,4])
MyList.__new__(MyList,[1,2,3,4])
list.__new__(MyList,[1,2,3,4])
这将返回MyList
的新实例,没有任何元素。 list.__new__
未填充列表。它留给list.__init__
,永远不会被调用。__new__
方法将'FirstMen'
附加到空MyList
个实例。__new__
方法会返回MyList
。MyList.__init__([1,2,3,4])
被调用。name
属性设置为'Westeros'
。my_list
并已打印。请点击此处查看__new__
:http://docs.python.org/reference/datamodel.html#basic-customization