Examples to illustrate Python references and objects

I saw such a strange sentence today:  variable names and objects in python are separated ; at first, I didn't react when I saw this sentence. Decided to figure out the details between variables and objects in python. (Actually, I feel that it is more appropriate to say that references and objects are separated)

  Start thinking with the first variable:

   In python, if you want to use a variable, you don't need to declare it in advance, you only need to assign a value to the variable when you use it (this is different from statically typed languages ​​such as C language, and python is dynamically typed).

   Take the first chestnut:

    a = 1

   This is a simple assignment statement. The integer 1 is an object, and a is a reference. Using the assignment statement, the reference a points to the object 1; The "line" in the hand, python is just like that "line", by reference to touch and tie the kite in the sky - the object.

   You can view the identity of an object through python's built-in function id(), which is actually the memory address of the object:

    Note:

     Python's concept of everything is an object, so a function is also an object, so you can use the __doc__ method of the id() function to view the specific description of this function.


Let's take an example first:

>>> a = 1
>>> id(a)
24834392
>>> a = 'banana'
>>> id(a)
139990659655312

In the first statement, 2 is an integer object stored in the memory, and the reference a points to object 1 through assignment; in

the second statement, a string object 'banana' is created in the memory, and the reference a points to the object 1 through assignment 'banana', at the same time, object 1 no longer has a reference to it, it will be garbage collected by python's memory handling mechanism to free the memory.


Another example:

>>> a = 1
>>> id(a)
24834392
>>> a = 'banana'
>>> id(a)
139990659655312

In the first statement, 2 is an integer object stored in the memory, and the reference a points to object 1 through assignment; in

the second statement, a string object 'banana' is created in the memory, and the reference a points to the object 1 through assignment 'banana', at the same time, object 1 no longer has a reference to it, it will be garbage collected by python's memory handling mechanism to free the memory.

 

Another example:
 

View the reference of variable a and variable b through the function: 

1

2

3

4

5

6

>>> a = 3

>>> b = 3

>>> id(a)

10289448

>>> id(b)

10289448

  Here you can see that these two references point to the same object, why? This is related to python's memory mechanism, because for the language, frequent object destruction and creation is a waste of performance. So in Python, integers and short characters, Python caches these objects for reuse.


Then look at this example again:
 

 1.  a = 4

    2. b = a (here is to let reference b point to the object pointed to by reference a)

    3.  a = a + 2

   View references by function:

    When you get to step 2, look at the references to a and b:      

1

2

3

4

5

6

>>> a = 4

>>> b = a

>>> id(a)

36151568

>>> id(b)

36151568

    You can see that both a and b point to integer objects 4

    Next point to step 3:

1

2

3

4

5

>>> a = a+2

>>> id(a)

36151520

>>> id(b)

36151568

    It can be seen that the reference of a has changed, but the reference of b has not changed; a and b point to different objects; the third sentence reassigns a to point to a new object 6; even if multiple references point to different objects For the same object, if a reference value changes, it actually makes the reference point to a new reference, and does not affect the pointing of other references. From the effect point of view, each reference is independent of each other and does not affect each other.
 

One more must-see example:

l1 = []
a = 0
for i in range(1,5):
    a = i
    l1.append(a) # 添加的是a指向的对象
print(l1) # [1, 2, 3, 4]

l2 = []
b = [1,2,3]
for i in range(1,5):
    b[1] = i
    l2.append(b) # 添加的是b指向的对象,它包括列表元素的引用,列表本身没有改变,只是列表项[1]指向的对象变了
print(l2) # [[1, 4, 3], [1, 4, 3], [1, 4, 3], [1, 4, 3]]
# 不是预料的 [[1, 1, 3], [1, 2, 3], [1, 3, 3], [1, 4, 3]]

So, each time the list is actually adding the same object.

l2 = []
b = [1,2,3]
for i in range(1,5):
    b[1] = i
    l2.append(copy.copy(b))
    # l2.append(copy.deepcopy(b)) 和copy.copy()结果一样
print(l2) # [[1, 1, 3], [1, 2, 3], [1, 3, 3], [1, 4, 3]]

copy.copy() Shallow copy. Only the parent object is copied, not the internal child objects of the object.

So, what is the difference between copy.copy() and copy.deepcopy()?

l2 = []
b = [1,[4,5],3]
for i in range(1,5):
    b[1][0] = i
    l2.append(copy.copy(b)) # [[1, [4, 5], 3], [1, [4, 5], 3], [1, [4, 5], 3], [1, [4, 5], 3]]
    # l2.append(copy.deepcopy(b)) # [[1, [1, 5], 3], [1, [2, 5], 3], [1, [3, 5], 3], [1, [4, 5], 3]]
print(l2)

copy.deepcopy() Deep-copy the copied object and its sub-objects.

The last example:

(this chestnut will involve mutable data types and immutable data types in python):

   Before starting this chestnut, remember to notice the difference in the fourth chestnut.

     1.   L1 = [1, 2, 3]

     2. L2 = L1

     3.   L1[0] = 10

   View references by function:

   When performing steps 1 and 2, look at the references to L1 and L2:

1

2

3

4

5

6

>>> L1 = [1,2,3]

>>> L2 = L1

>>> id(L1)

139643051219496

>>> id(L2)

139643051219496

At this time, the references of L1 and L2 are the same, and both point to the list object [1,2,3].

Next, proceed to step 3:

1

2

3

4

5

6

7

>>> L1[0= 10

>>> id(L1)

139643051219496

>>> id(L2)

139643051219496

>>> L2

[1023]

同样的跟第四个栗子那样,修改了其中一个对象的值,但是可以发现 结果 并不与 第四个栗子那样, 在本次实验中,L1 和 L2 的引用没有发生任何变化,但是 列表对象[1,2,3] 的值 变成了 [10,2,3](列表对象改变了)


在该情况下,我们不再对L1这一引用赋值,而是对L1所指向的表的元素赋值。结果是,L2也同时发生变化。


原因何在呢?因为L1,L2的指向没有发生变化,依然指向那个表。表实际上是包含了多个引用的对象(每个引用是一个元素,比如L1[0],L1[1]..., 每个引用指向一个对象,比如1,2,3), 。而L1[0] = 10这一赋值操作,并不是改变L1的指向,而是对L1[0], 也就是表对象的一部份(一个元素),进行操作,所以所有指向该对象的引用都受到影响。

(与之形成对比的是,我们之前的赋值操作都没有对对象自身发生作用,只是改变引用指向。)


列表可以通过引用其元素,改变对象自身(in-place change)。这种对象类型,称为可变数据对象(mutable object),词典也是这样的数据类型。


而像之前的数字和字符串,不能改变对象本身,只能改变引用的指向,称为不可变数据对象(immutable object)。


我们之前学的元组(tuple),尽管可以调用引用元素,但不可以赋值,因此不能改变对象自身,所以也算是immutable object.

感谢阅读上海尚学堂python文章,获取更多文章和技术支持,请点击 上海Python培训
 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325173670&siteId=291194637