Python:如何从内置列表类型继承?
我想向内置 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
这样的不可变类型也是一样吗?
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
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
list
类型通常在其__init__()
方法中实际初始化列表,因为它是可变类型的约定。当子类型化不可变类型时,您只需要覆盖__new__()
。虽然您可以在子类化列表时覆盖__new__()
,但对于您的用例来说这样做没有多大意义。覆盖__init__()
会更容易:另请注意,我建议在这种情况下不要使用
super()
。您想在此处调用list.__init__()
,而不是其他任何内容。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__()
:Also note that I recommend against using
super()
in this case. You want to calllist.__init__()
here, and not possibly anything else.首先,您这样做是为了理解
__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-customizationFirst 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:
MyList([1,2,3,4])
MyList.__new__(MyList,[1,2,3,4])
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 tolist.__init__
, which is never called.__new__
method appends'FirstMen'
to the emptyMyList
instance.__new__
method returns the instance ofMyList
.MyList.__init__([1,2,3,4])
is invoked.name
attribute to'Westeros'
.my_list
and printed.See here for an explanation of
__new__
: http://docs.python.org/reference/datamodel.html#basic-customization