下面是一个用于保存列表的类,并将提供给它的任何新值添加到列表中(以及能够打印列表):
class foobar:
def __init__(self, value=None):
if type(value) is str:
self.value = [value]
else:
self.value = ['']
def __iadd__(self, new_value):
self.value.append(new_value)
def add(self, new_value):
self.value.append(new_value)
def __str__(self):
return str(self.value)
功能 add
仅用于测试目的。
出现的这个问题是对象add
和__iadd__()
的两个功能的行为不同。或者我以为...
实际上,上面提到的两个函数会产生相同的结果,但是add
和+=
会产生不同的结果。
示例运行:
>>> testStr = foobar()
>>> testStr
<__main__.foobar instance at 0x00000000034CCE48>
>>> print testStr
['']
>>> testStr.add('val1')
>>> testStr
<__main__.foobar instance at 0x00000000034CCE48>
>>> print testStr
['', 'val1']
>>> testStr.__iadd__('val2')
>>> testStr
<__main__.foobar instance at 0x00000000034CCE48>
>>> print testStr
['', 'val1', 'val2']
>>> testStr += 'val3'
>>> testStr
>>> print testStr
None
如您所见,+=
操作将testStr
的{{1}}实例转换为foobar
,从而(显然)删除其中包含的值。
据我了解,NoneType
和__iadd__()
运算符的行为应相同,但事实并非如此。可以在这里实现+=
来适当更新__iadd__()
的行为,还是这种类型的操作有问题?
答案 0 :(得分:1)
__iadd__
必须返回更新的对象(可以是self
):
def __iadd__(self, new_value):
self.value.append(new_value)
return self
您没有返回任何内容,因此使用了None
(默认返回值)。
这些方法应尝试就地进行操作(修改 self )并返回结果(可以但不一定是自我)。 [...] 例如,如果
x
是具有__iadd__()
方法的类的实例,则x += y
等效于{{1 }} 。
强调粗体;请注意x = x.__iadd__(y)
的等效项。