This article mainly describes the python expression i + = x and i = i + x is the equivalent of the data, the text through the sample code introduced in very detailed, I believe that we have a certain reference value, the need for friends to see together below.
Objective
Recently saw a topic, seemingly very simple, in fact, there is a deep meaning, the topic is the python expression i + = x and i = i + x equivalent? If your answer is yes, then congratulate you on the right 50%, why say only half? According to our general understanding of the two are equivalent, integer operation when the two are not the same, but for the list of operations, is not the same?
Let's look at the following two pieces of code:
Code 1
>>> L1 = Range (3) >>> L2 = l1>>> L2 + = [3]>>> l1[0, 1, 2, 3]>>> l2[0, 1, 2, 3]
Code 2
>>> L1 = Range (3) >>> L2 = l1>>> L2 = L2 + [3]>>> l1[0, 1, 2]>>> l2[0, 1, 2, 3 ]
Code 1 is the same as the value of L2 in code 2, but the value of L1 is not the same, stating that i + = x and i = i + x is not equivalent, then what is the equivalent, under what circumstances is not equivalent?
Before figuring out the problem, it is preferable to understand two concepts: mutable objects and immutable objects.
There are three common properties for any object in Python: A unique identity, a type, and a value.
unique Identity: the in-memory uniqueness used to identify an object, which will no longer change after the object is created, and the function ID () to see the object's unique identity
type: determines which operations are supported by the object, different types of objects support the same action, such as the list can have the length property, and the integer does not. Similarly, once the type of the object is determined, it will no longer change, and the function type () can return the type information of the object.
The value of an object is not the same as a unique identity, not all of the values of the object are immutable, the values of some objects can be changed by some operations, the value can change the object is called a mutable object (mutable), the value cannot change the object is called the immutable object (immutable)
Immutable Objects (immutable)
For an immutable object, the value is always the value at the beginning of the creation, and any action on that object will result in the creation of a new object.
>>> a = 1>>> ID (a) 32574568>>> A + = 1>>> ID (a) 32574544
The integer "1" is an immutable object, when initially assigned, a points to an integer object 1, but after you perform the + = operation on variable A, a points to another integer object 2, but the object 1 is still there without any change, and variable a already points to a new object 2. Common immutable objects are: int, tuple, set, str.
mutable Objects (mutable)
The values of Mutable objects can be changed dynamically by certain operations, such as list objects, which can be continuously added to the list by the Append method, and the value of the list is constantly changing, and when a mutable object is assigned to two variables, they share the same instance object, pointing to the same memory address, When you operate on any one of these variables, it also affects the other variable.
>>> x = Range (3) >>> y = x>>> ID (x) 139726103041232>>> ID (y) 139726103041232>> > X.append (3) >>> x[0, 1, 2, 3]>>> y[0, 1, 2, 3]>>> ID (x) 139726103041232>>> ID (y) 13 9726103041232
After performing the append operation, the memory address of the object does not change, and X and Y still point to the same object, except that his value has changed.
After understanding the Mutable object and the immutable object, go back to the question itself, where is the difference between + = and +?
The + = operation First attempts to invoke the object's __iadd__ method, and if there is no method, try calling the __add__ method , first to see what the difference between the two methods
The difference between __add__ and __iadd__
The __add__ method receives two parameters, returns their values, and the value of the two parameters does not change.
The __iadd__ method also receives two parameters, but it belongs to the in-place operation, which means that it changes the value of the first parameter because it requires the object to be mutable, so there is no __iadd__ method for the immutable object.
>>> hasattr (int, ' __iadd__ ') false>>> hasattr (list, ' __iadd__ ') True
Obviously, the integer object is not __iadd__, and the list object provides the __iadd__ method.
>>> L2 + = [3] # code 1: Use the value of __IADD__,L2 to modify in situ
The + = operation in code 1 calls the __iadd__ method, where he modifies the value of the object itself that L2 points to
>>> L2 = L2 + [3] # code 2: Call __add__, create a new list, assign a value to the L2
While the + operation in code 2 calls the __add__ method, the method returns a new object, the original object remains unchanged, L1 points to the original object, and L2 has pointed to a new object.
The above is the difference between the expression i + = x and i = i + x. Therefore, there is a potential bug in the list + = operation, because the L1 will change because of the change of L2, just as the parameter of the function should not use the variable object as the keyword parameter.