Python类打印对象始终返回一个空列表

时间:2018-03-07 23:26:31

标签: python class oop

我有以下代码:

class Mylist(list):

    def __init__(self,lst=[]):
        self.lst=list(lst)

    def append(self,item):
        self.lst.append(item)
m=Mylist([1,2])
m.append(3)
m

直观地说,这段代码应该打印[1,2,3]或者[3]?但绝对不是[]。我想知道为什么会这样?虽然当我使用m.lst而不是m时,它会打印[1,2,3]。

3 个答案:

答案 0 :(得分:3)

由于MyList继承自list,因此它已包含append(和extend)通常会添加的项目的内部存储空间。当您print(m)时,会显示此内部存储空间。

在您的情况下,您已覆盖append以重定向要添加到单独属性(lst)的项目,这意味着内部存储空白。

请注意,您尚未覆盖extend。因此:

# this will add to the *internal* storage, not `.lst`
>>> m.extend(["my", "gosh"])`
>>> print(m)
['my', 'gosh']

答案 1 :(得分:0)

Mylist不以任何方式利用它的子类list这一事实。如果list实际上有一个lst属性本身就是一个列表,那么你的代码就可以工作,但事实并非如此。

如果希望覆盖的方法执行基础list对象拾取的操作,则需要使用从中继承的list对象的公开接口:

class MyList(list):
    def __init__(self, iterable):
        print('I was passed:', iterable)

        super().__init__(iterable)

    def append(self, element):
        print('I am appending the element:', element)

        super().append(element)

答案 2 :(得分:0)

如果您只想使用列表,则无需继承list,也不应该继承:

class Mylist: # no (list) here!
    def __init__(self,lst=[]):
        self.lst=list(lst)
    def append(self,item):
        self.lst.append(item)
m=Mylist([1,2])
m.append(3)

这很有效。当然,打印m会让你得到像<__main__.MyList at 0x12345678>这样的东西,因为你没有告诉它你想要如何打印。您需要添加另一种方法:

    def __repr__(self):
        return '{}({})'.format(type(self).__name__, self.lst)

现在你打印出MyList([1, 2, 3])

如果您希望外观,就像list一样,您仍然不会从list继承。在大多数情况下,在Python中,“看起来像列表”只是鸭子打字的问题:你实现所有正确的方法,一切正常。

但是,您可能需要考虑从MutableSequence继承。然后,您只需实现大约7或8个方法,并且您可以免费获得list的所有其余行为。而且你还提供了一种代码,无论出于什么原因,需要明确检查你是否“像列表一样”的代码可以这样做。

那么,当应该你从list继承?当您想要将list的内部存储和实现用作您自己的存储和实现时。

这是一个愚蠢的例子。如果它有任何理由存在,那么它应该是list子类是合理的:

class FreezableList(list):
    def frozen_copy(self):
        return tuple(self)
    def __repr__(self):
        return '{}({})'.format(type(self).__name__, self.lst)