国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

Python中的引用和拷貝淺析

2019-11-25 18:04:31
字體:
來源:轉載
供稿:網友

If an object's value can be modified, the object is said to be mutable. If the value cannot be modified,the object is said to be immutable.

mutable 可變類型,例如 list,set,自定義類型(等價于C#中的引用類型);

immutable 不可變類型,例如string,numbers等(等價于C#中的值類型);

一、引用和拷貝(references and copies)

當程序中使用=賦值操作符時,例如a=b,

對于不可變的對象,a作為b的一個拷貝被創建,a和b將指向不同的內存地址,a和b相互獨立。

復制代碼 代碼如下:

def TestCopy():
    a = 10
    b = a
    a =20
    print (b) #b still is 10

但是對于可變的對象,a作為b的一個引用被創建,a和b的元素公用相同的內存地址,a和b的元素共享。
復制代碼 代碼如下:

def TestRef():
    a=[1,2,3,4]
    b=a   #b is a reference to a
    print (b is a) # True
    b[2] = -100 #change an element in b
    print (a) # a also changed to [1,2,-100,4]

二、深拷貝和淺拷貝(shallow copy and deep copy)

為了避免可變對象指向同一個對象,必須創建一個新的拷貝,而不是引用。
在python中可以對容器對象(例如lists和dictionaries)使用兩種拷貝:淺拷貝和深拷貝。
 
淺拷貝創建一個新的對象,但是使用原來對象的元素的引用(如果是不變類型,相當于是拷貝)來填充新對象。可以使用copy.copy()來實現淺拷貝。

復制代碼 代碼如下:

def TestShallowCopy():
    a = [ 1, 2, [3,4] ]
    b = list(a) # create a shallow copy of a
    print (b is a) #False
    b.append(100) #append element to b
    print (b)
    print (a) # a is unchanged
    b[2][0] = -100 # modify an element inside b
    print (b)
    print (a)  # a is changed

在這個例子中,a和b共享相同的可變元素。所以修改其中一個list對象中的元素,另一個list對象也會被修改。

深拷貝創建一個新的對象,同時遞歸地拷貝對象所包含的所有的元素。可以使用copy.deepcopy()來實現深拷貝。

復制代碼 代碼如下:

def TestDeepCopy():
  import copy
  a = [1, 2, [3, 4]]
  b = copy.deepcopy(a)
  b[2][0] = -100
  print (b)  # b is changed
  print (a)  # a is unchanged

在這個例子中,a和b是對立的list對象,且他們的元素也相互獨立。

三、引用計數和垃圾回收

python中的所有的對象都是引用計數的,一個對象賦值或加入容器時,它的引用計數就會自增,當使用del時或變量賦值為其他值時,引用計數就會自減,當引用計數為0時,python的垃圾回收器就會回收該變量。

復制代碼 代碼如下:

def TestGarbageCollection():
  import sys
  print(sys.getrefcount(37))
  a = 37 # Creates an object with value 37
  print(sys.getrefcount(37))
  b = a # Increases reference count on 37
  print(sys.getrefcount(37))
  c = []
  c.append(b) # Increases reference count on 37
  print(sys.getrefcount(37))
  del a # Decrease reference count of 37
  print(sys.getrefcount(37))
  b = 42 # Decrease reference count of 37
  print(sys.getrefcount(37))
  c[0] = 2.0 # Decrease reference count of 37
  print(sys.getrefcount(37))
 
TestGarbageCollection()

運行結果為:

復制代碼 代碼如下:

11
12
13
14
13
12
11

為啥一上來就有11個引用了呢?誰知道?

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 安阳县| 宁晋县| 平度市| 花莲市| 特克斯县| 大悟县| 平舆县| 巩留县| 济源市| 霍山县| 来安县| 体育| 德清县| 绥阳县| 舞钢市| 腾冲县| 辽中县| 乌恰县| 大化| 安溪县| 图木舒克市| 安丘市| 许昌县| 新民市| 麻江县| 九龙县| 福贡县| 尚义县| 永平县| 邵东县| 酉阳| 工布江达县| 南阳市| 万全县| 岳阳市| 来凤县| 克山县| 永康市| 高碑店市| 禄丰县| 长海县|