Luk*_*are 55 python operator-overloading python-3.x
一个代码块有效,但另一个代码没有.哪个是有意义的,除了第二个块与第一个块相同,只是用速记写的操作.它们实际上是相同的操作.
l = ['table']
i = []
Run Code Online (Sandbox Code Playgroud)
for n in l:
i += n
print(i)
Run Code Online (Sandbox Code Playgroud)
输出: ['t', 'a', 'b', 'l', 'e']
for n in l:
i = i + n
print(i)
Run Code Online (Sandbox Code Playgroud)
输出:
TypeError:只能将列表(不是"str")连接到列表
是什么导致了这个奇怪的错误?
tim*_*geb 79
它们不必相同.
使用+
操作员__add__
在使用+=
操作员调用时调用该方法__iadd__
.完全取决于所讨论的对象,当调用其中一个方法时会发生什么.
如果您使用x += y
但未x
提供__iadd__
方法(或方法返回NotImplemented
),则将__add__
其用作后备,意味着x = x + y
会发生这种情况.
在列表的情况下,使用l += iterable
实际扩展列表l
的元素iterable
.在您的情况下,extend
操作期间会附加字符串中的每个字符(可迭代).
演示1:使用 __iadd__
>>> l = []
>>> l += 'table'
>>> l
['t', 'a', 'b', 'l', 'e']
Run Code Online (Sandbox Code Playgroud)
演示2:使用extend
也是如此
>>> l = []
>>> l.extend('table')
>>> l
['t', 'a', 'b', 'l', 'e']
Run Code Online (Sandbox Code Playgroud)
演示3:添加列表和字符串引发a TypeError
.
>>> l = []
>>> l = l + 'table'
[...]
TypeError: can only concatenate list (not "str") to list
Run Code Online (Sandbox Code Playgroud)
不使用+=
会给你TypeError
这里,因为只__iadd__
实现扩展行为.
演示4:常见陷阱:+=
不构建新列表.我们可以通过检查与is
操作员相同的对象身份来确认这一点.
>>> l = []
>>> l_ref = l # another name for l, no data is copied here
>>> l += [1, 2, 3] # uses __iadd__, mutates l in-place
>>> l is l_ref # confirm that l and l_ref are names for the same object
True
>>> l
[1, 2, 3]
>>> l_ref # mutations are seen across all names
[1, 2, 3]
Run Code Online (Sandbox Code Playgroud)
但是,l = l + iterable
语法确实构建了一个新列表.
>>> l = []
>>> l_ref = l # another name for l, no data is copied here
>>> l = l + [1, 2, 3] # uses __add__, builds new list and reassigns name l
>>> l is l_ref # confirm that l and l_ref are names for different objects
False
>>> l
[1, 2, 3]
>>> l_ref
[]
Run Code Online (Sandbox Code Playgroud)
在某些情况下,这可能会产生细微的错误,因为它会+=
改变原始列表,同时
l = l + iterable
构建一个新列表并重新分配名称l
.
奖金