日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python 对象引用、可变性 和 垃圾回收

發布時間:2024/7/5 python 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python 对象引用、可变性 和 垃圾回收 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

    • 1. 變量是標簽
    • 2. 元組的相對不可變性
    • 3. 默認淺復制
    • 4. 函數的參數作為引用時
    • 5. del 和 垃圾回收
    • 6. 弱引用
    • 7. 一些可能的坑!!!

learn from 《流暢的python》

1. 變量是標簽

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

  • 對象的 id 在生命周期中是不變的
  • is 運算檢查兩者的 id 是否一致
  • == 檢查兩者內容(值)是否一樣
  • is 運算符比 == 速度快,因為它不能重載,不用尋找并調用特殊方法

2. 元組的相對不可變性

元組的不可變性 其實是指 tuple 數據結構的 物理內容(即保存的引用)不可變,與引用的對象無關

>>> t1 = (1, 2, [30, 40]) >>> t2 = (1, 2, [30, 40]) >>> t1 is t2 False >>> t1 == t2 True >>> id(t1[-1]) 2633996005896 >>> t1[-1].append(100) >>> t1 (1, 2, [30, 40, 100]) >>> id(t1[-1]) 2633996005896 >>> t1 == t2 False

如果元組內部有 可變對象,那么元組就 不可散列了

3. 默認淺復制

>>> l1 = [3, [55, 44], (7, 8, 9)] >>> l2 = list(l1) # 創建副本 或者 [:] ,淺復制 >>> l2 [3, [55, 44], (7, 8, 9)] >>> l1 == l2 True >>> l1 is l2 False

構造方法[:] 做的是淺復制(即復制了最外層容器,副本中 的元素是源容器中元素的引用)。
如果所有元素都是不可變的,那么這 樣沒有問題,還能節省內存。
但是,如果有可變的元素,可能就會導致 意想不到的問題。

>>> l1 = [3, [66, 55, 44], (7, 8, 9)] >>> l2 = list(l1) # 兩者共享內部的 list tuple >>> l1.append(100) >>> l1[1].remove(55) >>> print('l1:', l1) l1: [3, [66, 44], (7, 8, 9), 100] >>> print('l2:', l2) l2: [3, [66, 44], (7, 8, 9)] >>> l2[1] += [33, 22] # list 變更,反映到 l1 >>> l2[2] += (10, 11) # tuple 不可變,+= 生成新的 tuple ,不反映到 l1 >>> print('l1:', l1) l1: [3, [66, 44, 33, 22], (7, 8, 9), 100] >>> print('l2:', l2) l2: [3, [66, 44, 33, 22], (7, 8, 9, 10, 11)]


  • copy 模塊 的 deepcopy(),copy() 實現 深復制,淺復制

4. 函數的參數作為引用時

  • 可變對象 經過函數修改會傳遞出來(如果不希望修改原來的,可以創建副本)
  • 不可變對象 操作后,會生成新的對象
  • 不要用 可變對象作為函數默認值,如 def func(a = [])
>>> def func(a=[]): ... a.append(5) ... print(a) ... >>> func() [5] >>> func() [5, 5] >>> func() [5, 5, 5]

修改了 可變的默認值,后續調用都會受到影響

5. del 和 垃圾回收

del 語句刪除名稱,而不是對象
del 命令可能會導致對象被 當作垃圾 回收,但是 僅當 刪除的變量 保存的是 對象的最后一個引用,或者無法得 到對象時

6. 弱引用

正是因為有引用,對象才會在內存中存在。

當對象的引用數量歸零后, 垃圾回收程序會把對象銷毀。

但是,有時需要引用對象,而不讓對象 存在的時間超過所需時間。這經常用在緩存中。

弱引用不會增加對象的引用數量。
引用的目標對象 稱為 所指對象 (referent)。弱引用 不會妨礙 所指對象被當作垃圾回收。
弱引用在緩存應用中很有用,因為我們 不想僅因為 被緩存引用著 而始終 保存緩存對象

7. 一些可能的坑!!!

>>> a = None >>> b = None >>> a is b True >>> id(a) 140712131987472 >>> id(b) 140712131987472 >>> a = [1,2] >>> b = [1,2] >>> a is b False >>> a = (1,2) # list , tuple 相同字面量,id 不同 >>> b = (1,2) >>> a is b False >>> a = "haha" # 相同的字面量字符串,id 一樣!! >>> b = "haha" >>> a is b True >>> a = 5 >>> b = 5 >>> a is b True >>> a, b = 0 , 0 >>> a is b True >>> a = 5 >>> a 5 >>> b 0 >>> a = "ha" >>> b = "ha" >>> a is b True >>> a = "good" # 但是也無須擔心。。 >>> a 'good' >>> b 'ha' >>> a = [1,2] >>> b = a[:] >>> b [1, 2] >>> a is b False >>> a = (1,2) >>> b = a[:] # 不創建新的副本,而list會創建新的副本 >>> b (1, 2) >>> a is b True >>> b = tuple(a) # 不創建新的副本,而list會創建新的副本 >>> a is b True >>> a = [1,2] >>> b = list(a) # list 創建副本 >>> b [1, 2] >>> a is b False

總結

以上是生活随笔為你收集整理的python 对象引用、可变性 和 垃圾回收的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。