Joh*_*ica 107
是的,覆盖__iadd__
方法.例:
def __iadd__(self, other):
self.number += other.number
return self
Run Code Online (Sandbox Code Playgroud)
Pet*_*tri 21
除了上面的答案中正确给出的内容之外,值得明确说明当__iadd__
重写时,x += y
操作不会以__iadd__
方法结束结束.
相反,它结束于x = x.__iadd__(y)
.换句话说,Python __iadd__
在实现完成后将实现的返回值分配给您"添加到"的对象.
这意味着可以改变操作的左侧,x += y
以便最后的隐式步骤失败.考虑当您添加到列表中的内容时会发生什么:
>>> x[1] += y # x has two items
现在,如果你的__iadd__
实现(一个对象的方法x[1]
)错误地或有意地x[0]
从列表的开头删除第一个item(),那么Python将运行你的__iadd__
方法)并尝试将其返回值赋值给x[1]
.哪个将不再存在(它将在x[0]
),从而产生一个ÌndexError
.
或者,如果您在上面的示例的__iadd__
开头插入了一些内容,那么您x
的对象将处于x[2]
,而不是x[1]
之前的任何内容,并且x[0]
将x[1]
被赋予__iadd__
调用的返回值.
除非人们理解正在发生的事情,否则产生的错误可能是一个噩梦.
小智 12
除了重载__iadd__
(记得返回self!),你还可以回退__add__
,因为x + = y将像x = x + y一样工作.(这是+ =运算符的缺陷之一.)
>>> class A(object):
... def __init__(self, x):
... self.x = x
... def __add__(self, other):
... return A(self.x + other.x)
>>> a = A(42)
>>> b = A(3)
>>> print a.x, b.x
42 3
>>> old_id = id(a)
>>> a += b
>>> print a.x
45
>>> print old_id == id(a)
False
Run Code Online (Sandbox Code Playgroud)
它甚至惹恼了专家:
class Resource(object):
class_counter = 0
def __init__(self):
self.id = self.class_counter
self.class_counter += 1
x = Resource()
y = Resource()
Run Code Online (Sandbox Code Playgroud)
你期望什么样的价值观x.id
,y.id
以及Resource.class_counter
有哪些?
http://docs.python.org/reference/datamodel.html#emulating-numeric-types
例如,要执行语句x + = y,其中x是具有__iadd __()方法的类的实例,则调用x .__ iadd __(y).
归档时间: |
|
查看次数: |
37127 次 |
最近记录: |