关于UserList __init__,([:],isinstance)的问题

时间:2018-11-07 09:54:43

标签: python python-3.x cpython

我想用一些自定义方法扩展python37中的类列表。 并最终阅读了UserList cpython code。阅读后,关于[:]用法的新问题出现了。

如果我正确理解`[:]`会复制整个切片 self.data但是我试图看看使用`[:]`有什么意义。 在“ =”运算符的左侧。

选项1和2之间有区别吗?在python中试过 解释器,而且两者似乎具有相同的效果,我是否想念 什么?

letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
# option (1)
letters[:] = []
# option (2)
letters = []

现在出现有关UserList代码的问题。我添加了关于我有问题的评论。

class UserList(_collections_abc.MutableSequence):
    def __init__(self, initlist=None):
        self.data = []
        if initlist is not None:
            if type(initlist) == type(self.data):
            # NOTE: Is this if statement doing the same?
            # if isinstance(initlist, list):
                self.data[:] = initlist
                # NOTE: wouldn't in this case self.data keep a reference to initlist
                # instead of a copy?
                # self.data[:] = initlist[:]  # could one replace that line with this one?
            elif isinstance(initlist, UserList):
                self.data[:] = initlist.data[:]
                # NOTE: would this line accomplish the same?
                # self.data = initlist.data[:]
            else:
                self.data = list(initlist)
    ...

2 个答案:

答案 0 :(得分:3)

如果您另外引用letters,则它们的行为会有所不同。

方案1:在适当位置修改letters

>>> letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> lst = letters
>>> letters[:] = []
>>> letters
>>> []
>>> lst
>>> []

方案2,将名称letters重新分配给一个空列表。

>>> letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> lst = letters
>>> letters = []
>>> letters
>>> []
>>> lst
>>> ['a', 'b', 'c', 'd', 'e', 'f', 'g']

由于names are reassigned independentlylst没有任何变化。

如果有

self.data = initlist

initlist的突变会影响self.data(因为它们是内存中的同一对象)。

答案 1 :(得分:0)

当在=运算符的左侧指定a时,您正在使用Python的常规分配,该分配会在当前上下文中将名称a更改为指向新值。这不会更改a指向的先前值。

通过在=运算符的左侧指定a [0:2],您告诉Python您要使用切片分配。切片分配是列表的一种特殊语法,您可以在其中插入,删除或替换列表中的内容。 参见:How assignment works with python list slice

也许这对您有帮助。