Mutable objects and immutable objects
All objects in Python. There is no so-called value-passing call in Python, all passing is a reference to the object, or it can be considered as a pass-through.
In Python, objects are divided into variable (mutable) and immutable (immutable) types, tuples (tuple), numeric (number), string (strings) are immutable objects, and word-typical (dictionary) and list-type (lists) Object is a mutable object.
Immutable objects
See an example to analyze the characteristics of immutable objects
Python built-in ID () function that returns the unique identity (identity) of an object. The ID () returns the decimal, the actual memory address of the object is hex (object), and the ID () is used equivalent to Hex (ID ()) in this article.
>>>A= 1 #将变量a与内存中的值为1的内存绑定在一起>>>A= 2 # Bind the variable A to memory with a value of 2 in memory, not modify the original a bound memory value . # At this point, the original value of 1 memory address of the reference number minus one, when the reference count is 0 o'clock, the memory address is recycled>>>B=A# variable B binds to the same memory as a>>> ID(b),ID(a)# Print a A/b bound memory address(1972461824,1972461824)>>>B= 3 # Create a memory address with a memory value of 3 bound to the variable name B. At this point, a still points to a memory address with a value of 2>>>A, B (2,3)>>> ID(b),ID(a)# Print a A/b bound memory address(1972461856,1972461824)
>>> x = 1 >>> y = 1 > >> z = 1 >>> x is ytrue >>> y is ztrue >>> id (x), id (y), id (z) (1972461792 , 1972461792 , 1972461792 )
The second example shows that because an integer is an immutable object, X, Y, Z, in memory, points to a memory address that has a value of 1.
The greatest advantage of an immutable object is that it reduces the memory footprint of duplicate values.
The downside is that, as shown in the first example, I'm going to modify the value of this variable binding, and if there is no memory block in memory for that value, then you have to re-open a piece of memory and bind the new address to the variable name.
Instead of modifying the value of the memory block that the variable originally pointed to, this gives a certain reduction in execution efficiency.
The original memory block will be referenced less than 1 because the variable is bound to other memory blocks.
Here is a diagram of the first example
mutable objects
Keep looking at an example
Example 1
>>>= [1]>>>=# a,b绑定同一内存地址,内存中值为[1]>>>id(a),id(b)(19910643348561991064334856)>>> b.append(2)>>> a,b([12], [12])
Variable names A and B are the same memory address of the binding, and the modification of the value corresponding to either variable is reflected on the other variable. In other words, the manipulation of a mutable object is a direct change to the object.
Example 2
>>>=[1]>>> b=[1]>>>id(a),id(b)(19910652582481991064760520)
Thus, variables with the same value in a Mutable object may not be bound to the same memory address, pointing to different objects.
Example 3
Using Mutable objects in function default parameter values There is a big hole. See example:
>>> def add_end (L= []): .... L.append ( ' End ' ) ... return L ... >>> add_end ([1 , 2 ]) [ 1 , 2 , ]>> Add_end ([A, b]) [[1 ], [1 ], ]>>> add_end () [ ' end ' ]>> add_end () [, ' end ' ]>>> add_end () [, , ]
This is normal when the function is called by normal parameters, but when calling the function with the default parameter, we think the answer should be [' End '], but it is as if the previous call remembers the last value.
What is the reason for this?
This may seem like a change in the default parameter value for each invocation. We use add_end.__defaults__ to see the default parameter changes of the function object
>>> def add_end (L= []): .... L.append ( ' End ' ) ... return L ... >>>, add_end.__defaults__ ([],) >>> add_end () [ Span class= "St", "End" ]>>> add_end.__defaults__ ([],) >>> add_end () [ ' end ' , ]>>> add_end () [ ' end ' , , ]>>> add_end.__defaults__ ([ , , ' End ' ],)
Each call to a function with a default parameter value changes the default parameter value of the function object, so the default parameter value of the next call is changed. The reason for this is because the default parameter value is a mutable object, causing each call to change the default parameter value .
As a result, you can avoid the hassle of designing objects as immutable objects as possible when programming.
Assignment manipulation Techniques---sequence unpacking (recursive unpacking)
The sequence that contains multiple values is untied and placed in the sequence of variables. The number of elements in the unpacking sequence must be the same as the value of the left variable, otherwise it will be an error, too many or too few parameters.
>>>Values= 1,2,3>>>Values1,2,3)>>>X, y=Values>>> Print(x, y, z)1 2 3>>>A,b,c= 1,2,3,4,5Traceback (most recent): File"<input>", line1,inch <Module>ValueError: Too many values to unpack (expected3)>>>A,b,c=1,2Traceback (most recent): File"<input>", line1,inch <Module>ValueError: notEnough values to unpack (expected3, got2)
You can use the asterisk operator * to collect values when unpacking an element in a sequence that has more than an extra number of variables.
>>> a,b,*c=1,2,3,4,5>>>print(a,b,c)12 [345]
Variable, immutable object and assignment skill sequence unpacking in Python