An augmented assignment expression like x += 1 can be rewritten as x = x + 1 to achieve a similar, but not exactly equal effect. In the augmented version, x is only evaluated once. Also, when possible, the actual operation is performed in-place, meaning that rather than creating a new object and assigning that to the target, the old object is modified instead.
These [__i*__] methods are called to implement the augmented arithmetic assignments (+=, -=, *=, @=, /=, //=, %=, **=, <<=, >>=, &=, ^=, |=). These methods should attempt to do the operation in-place (modifying self) and return the result (which could be, but does not have to be, self). If a specific method is not defined, the augmented assignment falls back to the normal methods. For instance, if x is an instance of a class with an __iadd__() method, x += y is equivalent to x = x.__iadd__(y) . Otherwise, x.__add__(y) and y.__radd__(x) are considered, as with the evaluation of x + y. In certain situations, augmented assignment can result in unexpected errors (see Why does a_tuple[i] += ["item"] raise an exception when the addition works?), but this behavior is in fact part of the data model.
如前所述,
b += 1
更新b
到位,而a = a + 1
计算a + 1
,然后将名称a
分配给结果(现在a
不再指A
行)。为了正确理解
+=
运算符,我们还需要理解可变与不可变对象的概念。考虑一下当我们忽略.reshape
时会发生什么:我们看到
C
是而不是更新,这意味着c += 1
和c = c + 1
是等价的。这是因为现在C
是一个1D数组(C.ndim == 1
),所以当在C
上迭代时,每个整数元素都被拉出并分配给c
。现在在Python中,整数是不可变的,这意味着不允许就地更新,有效地将
c += 1
转换为c = c + 1
,其中c
现在指的是一个不以任何方式耦合到C
的新的整数。当您循环经过整形的数组时,整行(np.ndarray
)一次被分配给b
(和a
),这是可改变的对象,这意味着您可以随意插入新整数,这在您执行a += 1
时发生。应该提到的是,尽管} 方法以任何方式实现它们。
+
和+=
是如上所述相关的(而且通常是相关的),但是任何类型都可以通过分别定义__add__
和^{在第一个示例中,您正在重新分配变量
a
,而在第二个示例中,您正在使用+=
运算符就地修改数据。请参阅有关7.2.1. Augmented assignment statements 的部分:
+=
运算符调用^{+=
对象。另一方面,^{} 接受参数并返回它们的和(不修改它们)。
不同之处在于,一个修改数据结构本身(就地操作)
b += 1
,而另一个只是重新分配变量a = a + 1
。为了完整起见:
x += y
如果不总是执行就地操作,则(至少)有三个例外:如果
x
没有实现__iadd__
方法,那么x += y
语句只是x = x + y
的简写。如果x
与int
类似,就会出现这种情况。如果
__iadd__
返回NotImplemented
,Python将返回x = x + y
。从理论上讲,
__iadd__
方法可以实现为不工作。不过,那样做真的很奇怪。实际上,您的
b
s是实现__iadd__
并返回自身的numpy.ndarray
s,因此您的第二个循环将修改原始数组。你可以在Python documentation of "Emulating Numeric Types"中阅读更多关于这个的内容。
相关问题 更多 >
编程相关推荐