Reference and copy code examples of objects in Python

  • 2020-06-15 09:22:50
  • OfStack

You could say that Python has no assignment, only references. You create a structure that references itself, so you have an infinite loop. To understand this problem, there is a basic concept that needs to be clarified.

Python does not have "variables". What we usually call variables are just "labels" and references.

In python, "a=b" means that object a refers to object b, which itself does not allocate memory space separately (important: not copy!). , which points to the memory in the computer where the object b is stored. Therefore, if you want to copy an object to another object, you can't simply use the equal sign operation; you have to use other methods. If the object of the sequence class is (list, tuple), the slice operator (that is, ':') is used to make the copy.

When python makes an assignment like b = a, only 1 new reference to a is created, adding 1 to the reference count of a, rather than creating a new object:


>>> a = 'xyz'
>>> import sys
>>> sys.getrefcount(a)
3
>>> b = a
>>> sys.getrefcount(b)
4
>>> id(a)
88292288L
>>> id(b)
88292288L

Thus, when referenced objects are mutable objects (lists, dictionaries, mutable collections, etc.), unexpected behavior occurs:


>>> a = [1, 2, 3, 4]
>>> b = a
>>> b.append(5)
>>> a
[1, 2, 3, 4, 5]

Because a and b refer to the same object, if you change one object, the other object will change as well. When we want to make a copy instead of a reference, we can copy the object.

Copy object 1 using copy module:


>>> a = [1, 2, 3, 4]
>>> import copy
>>> b = copy.copy(a)
>>> b.append(5)
>>> b
[1, 2, 3, 4, 5]
>>> a
[1, 2, 3, 4]

This is fine, but this copy is a shallow copy, the copied new object contains a reference to the original object, if the object's items are mutable objects, will also cause uncontrollable behavior:


>>> a = [1, [1, 2]]
>>> b = copy.copy(a)
>>> b[1].append(3)
>>> b
[1, [1, 2, 3]]
>>> a
[1, [1, 2, 3]]

This is where deep copy comes in. Deep replication creates a new object and recursively copies all the objects it contains:


>>> a = [1, [1, 2]]
>>> b = copy.deepcopy(a)
>>> b[1].append(3)
>>> b
[1, [1, 2, 3]]
>>> a
[1, [1, 2]]

For immutable objects (strings, Numbers, tuples), etc., there is no need to copy them because they are immutable and you don't have to worry about inadvertently changing them. The copy operation will only result in the original object:


>>> a = (1, 2, 3)
>>> b = copy.copy(a)
>>> a is b
True

For mutable objects (lists, dictionaries, mutable collections), the built-in functions list(),dict(), and set() can be used for shallow replication faster than using the copy module.

Lists can also be lightly copied using slices:


>>> a = [1, 2, 3, 4]
>>> b = a[:]
>>> a is b
False
>>> b
[1, 2, 3, 4]

When * is performed on a sequence data type (string, list, tuple), the reference to the item in the object is simply copied. If * is used to create a multidimensional list:


>>> a = [1, 2, 3]
>>> b = [a]
>>> c = b * 3
>>> a.append(4)
>>> c
[[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]]

It is best to use shallow replication in list derivation to create multidimensional lists to avoid implicit reference sharing:


>>> a = [1, 2, 3]
>>> c = [list(a) for i in range(3)]
>>> a.append(4)
>>> c
[[1, 2, 3], [1, 2, 3], [1, 2, 3]]

conclusion

That's it for the reference and copy code examples in Python. Interested friends can continue to refer to other related topics in this site, if there is any deficiency, welcome to comment out.


Related articles: