关于 UserList __init__, ( [:], isinstance ) 的问题
Questions about UserList __init__, ( [:], isinstance )
我想用一些自定义方法扩展 python37 中的 class 列表。
并最终阅读了 UserList cpython code。阅读后,关于 [:]
用法的新问题出现了。
如果我理解正确的话,`[:]` 会制作一个整体的切片副本
`self.data`。但我想看看使用 `[:]` 有什么意义
在 `=` 运算符的左侧。
选项一和选项二有区别吗?在 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)
...
当您在 = 运算符的左侧指定 a 时,您使用的是 Python 的正常赋值,它会将当前上下文中的名称 a 更改为指向新值。这不会更改 a 指向的先前值。
通过在 = 运算符的左侧指定 [0:2],您告诉 Python 您想要使用切片分配。切片分配是列表的一种特殊语法,您可以在其中插入、删除或替换列表中的内容。
参见:How assignment works with python list slice
也许这对你有帮助。
如果您另一个引用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 independently,lst
没有看到任何变化。
如果你有
self.data = initlist
initlist
的突变会影响 self.data
(因为它们在内存中是同一个对象)。
我想用一些自定义方法扩展 python37 中的 class 列表。
并最终阅读了 UserList cpython code。阅读后,关于 [:]
用法的新问题出现了。
如果我理解正确的话,`[:]` 会制作一个整体的切片副本 `self.data`。但我想看看使用 `[:]` 有什么意义 在 `=` 运算符的左侧。
选项一和选项二有区别吗?在 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)
...
当您在 = 运算符的左侧指定 a 时,您使用的是 Python 的正常赋值,它会将当前上下文中的名称 a 更改为指向新值。这不会更改 a 指向的先前值。
通过在 = 运算符的左侧指定 [0:2],您告诉 Python 您想要使用切片分配。切片分配是列表的一种特殊语法,您可以在其中插入、删除或替换列表中的内容。 参见:How assignment works with python list slice
也许这对你有帮助。
如果您另一个引用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 independently,lst
没有看到任何变化。
如果你有
self.data = initlist
initlist
的突变会影响 self.data
(因为它们在内存中是同一个对象)。