python拷贝是什么知识点_python闭包、深浅拷贝、垃圾回收、with语句知识点汇总...
1.1 閉包
1、閉包概念
1. 在一個外函數中定義了一個內函數,內函數里運用了外函數的臨時變量,并且外函數的返回值是內函數的引用,這樣就構成了一個閉包
2. 一般情況下,在我們認知當中,如果一個函數結束,函數的內部所有東西都會釋放掉,還給內存,局部變量都會消失。
3. 但是閉包是一種特殊情況,如果外函數在結束的時候發現有自己的臨時變量將來會在內部函數中用到,就把這個臨時變量綁定給了內部函數,然后自己再結束。
2、閉包特點
1. 必須有一個內嵌函數
2. 內嵌函數必須引用外部函數中的變量
3. 外部函數的返回值必須是內嵌函數
#閉包函數的實例
def outer( a ):
b = 10
def inner(): # 在內函數中 用到了外函數的臨時變量
print(a+b) # 外函數的返回值是內函數的引用
return inner
if __name__ == '__main__':
demo = outer(5)
demo() # 15
# 在這里我們調用外函數傳入參數5
# 此時外函數兩個臨時變量 a是5 b是10 ,并創建了內函數,然后把內函數的引用返回存給了demo
# 外函數結束的時候發現內部函數將會用到自己的臨時變量,這兩個臨時變量就不會釋放,會綁定給這個內部函數
# 我們調用內部函數,看一看內部函數是不是能使用外部函數的臨時變量
# demo存了外函數的返回值,也就是inner函數的引用,這里相當于執行inner函數
閉包實例
3、閉包中內函數修改外函數局部變量
1、在基本的python語法當中,一個函數可以隨意讀取全局數據,但是要修改全局數據的時候有兩種方法:
1) global 聲明全局變量
2) 全局變量是可變類型數據的時候可以修改
2、在閉包情況下使用下面兩種方法修改
1)在python3中,可以用nonlocal 關鍵字聲明 一個變量, 表示這個變量不是局部變量空間的變量,需要向上一層變量空間找這個變量。
2)在python2中,沒有nonlocal這個關鍵字,我們可以把閉包變量改成可變類型數據進行修改,比如列表。
#修改閉包變量的實例
def outer( a ):
b = 10 # a和b都是閉包變量
c = [a] # 這里對應修改閉包變量的方法2
def inner():
# 方法一: nonlocal關鍵字聲明(python3)
nonlocal b
b+=1
# 方法二: 把閉包變量修改成可變數據類型 比如列表(python2)
c[0] += 1
print(c[0])
print(b)
return inner # 外函數的返回值是內函數的引用
if __name__ == '__main__':
demo = outer(5)
demo() # 6 11
閉包中內函數修改外函數局部變量
1.2 Python里的拷貝
1、預備知識一——python的變量及其存儲
1. python的一切變量都是對象,變量的存儲,采用了引用語義的方式,存儲的只是一個變量的值所在的內存地址,而不是這個變量的只本身
2. 不管多么復雜的數據結構,淺拷貝都只會copy一層。
理解:兩個人公用一張桌子,只要桌子不變,桌子上的菜發生了變化兩個人是共同感受的。
>>> str1 = 'hello'
>>> str2 = str1
#1、讓str1和str2變量都存儲了‘hello'所在的內存地址
>>> id(str1)
>>> id(str1)
>>>
#2、當str1的值變成‘new hello'后str1的值被重新賦值成'new hello'的內存地址,而str2的值依舊是‘hello'的內存地址
>>> str1 = 'new hello'
>>> id(str1)
>>> id(str2)
#3、不管多么復雜的數據結構,淺拷貝都只會copy一層。
>>> sourceList = [1,2,[3,4]]
>>> newList = sourceList
>>> l[2][0]=100
>>> sourceList
[1, 2, [100, 4]]
>>> newList
[1, 2, [100, 4]]
不管多么復雜的數據結構,淺拷貝都只會copy一層
2、淺copy與deepcopy
1、淺copy: 不管多么復雜的數據結構,淺拷貝都只會copy一層
2、deepcopy : 深拷貝會完全復制原變量相關的所有數據,在內存中生成一套完全一樣的內容,我們對這兩個變量中任意一個修改都不會影響其他變量
import copy
sourceList = [1,2,3,[4,5,6]]
copyList = copy.copy(sourceList)
deepcopyList = copy.deepcopy(sourceList)
sourceList[3][0]=100
print(sourceList) # [1, 2, 3, [100, 5, 6]]
print(copyList) # [1, 2, 3, [100, 5, 6]]
print(deepcopyList) # [1, 2, 3, [4, 5, 6]]
淺copy與deepcopy
1.3 Python垃圾回收機制
垃圾回收機制:
1、引用計數
1. 原理
1)當一個對象的引用被創建或者復制時,對象的引用計數加1;當一個對象的引用被銷毀時,對象的引用計數減1.
2)當對象的引用計數減少為0時,就意味著對象已經再沒有被使用了,可以將其內存釋放掉。
2. 優點
引用計數有一個很大的優點,即實時性,任何內存,一旦沒有指向它的引用,就會被立即回收,而其他的垃圾收集技術必須在某種特殊條件下才能進行無效內存的回收。
3. 缺點
1)引用計數機制所帶來的維護引用計數的額外操作與Python運行中所進行的內存分配和釋放,引用賦值的次數是成正比的,
2)這顯然比其它那些垃圾收集技術所帶來的額外操作只是與待回收的內存數量有關的效率要低。
3)同時,因為對象之間相互引用,每個對象的引用都不會為0,所以這些對象所占用的內存始終都不會被釋放掉。
2、標記-清除
1. 說明
1)它分為兩個階段:第一階段是標記階段,GC會把所有的活動對象打上標記,第二階段是把那些沒有標記的對象非活動對象進行回收。
2)對象之間通過引用(指針)連在一起,構成一個有向圖
3)從根對象(root object)出發,沿著有向邊遍歷對象,可達的(reachable)對象標記為活動對象,不可達的對象就是要被清除的非活動對象。
根對象就是全局變量、調用棧、寄存器。
注:像是PyIntObject、PyStringObject這些不可變對象是不可能產生循環引用的,因為它們內部不可能持有其它對象的引用。
1. 在上圖中,可以從程序變量直接訪問塊1,并且可以間接訪問塊2和3,程序無法訪問塊4和5
2. 第一步將標記塊1,并記住塊2和3以供稍后處理。
3. 第二步將標記塊2,第三步將標記塊3,但不記得塊2,因為它已被標記。
4. 掃描階段將忽略塊1,2和3,因為它們已被標記,但會回收塊4和5。
2、缺點
1)標記清除算法作為Python的輔助垃圾收集技術,主要處理的是一些容器對象,比如list、dict、tuple等
因為對于字符串、數值對象是不可能造成循環引用問題。
2)清除非活動的對象前它必須順序掃描整個堆內存,哪怕只剩下小部分活動對象也要掃描所有對象。
3、分代回收
1. 分代回收是建立在標記清除技術基礎之上的,是一種以空間換時間的操作方式。
2. Python將內存分為了3“代”,分別為年輕代(第0代)、中年代(第1代)、老年代(第2代)
3. 他們對應的是3個鏈表,它們的垃圾收集頻率與對象的存活時間的增大而減小。
4. 新創建的對象都會分配在年輕代,年輕代鏈表的總數達到上限時,Python垃圾收集機制就會被觸發
5. 把那些可以被回收的對象回收掉,而那些不會回收的對象就會被移到中年代去,依此類推
6. 老年代中的對象是存活時間最久的對象,甚至是存活于整個系統的生命周期內。
1.4 上下文管理(with)
1、什么是with語句
1. with是一種上下文管理協議,目的在于從流程圖中把 try,except 和finally 關鍵字和資源分配釋放相關代碼統統去掉,簡化try….except….finlally的處理流程。
2. 所以使用with處理的對象必須有enter()和exit()這兩個方法
1)with通過enter方法初始化(enter方法在語句體執行之前進入運行)
2)然后在exit中做善后以及處理異常(exit()方法在語句體執行完畢退出后運行)
2、with語句使用場景
1. with 語句適用于對資源進行訪問的場合,確保不管使用過程中是否發生異常都會執行必要的“清理”操作,釋放資源
2. 比如文件使用后自動關閉、線程中鎖的自動獲取和釋放等。
3、with處理文件操作的實例
with open('/etc/passwd') as f:
for line in f:
print(line)
# 這段代碼的作用:打開一個文件,如果一切正常,把文件對象賦值給f,然后用迭代器遍歷文件中每一行,當完成時,關閉文件;
# 而無論在這段代碼的任何地方,如果發生異常,此時文件仍會被關閉。
到此這篇關于python閉包、深淺拷貝、垃圾回收、with語句知識點匯總的文章就介紹到這了,更多相關python閉包&深淺拷貝&垃圾回收&with語句內容請搜索python博客以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持python博客!
總結
以上是生活随笔為你收集整理的python拷贝是什么知识点_python闭包、深浅拷贝、垃圾回收、with语句知识点汇总...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mongodb 日期分组聚合_mongo
- 下一篇: 增量索引和全量索引_搜索引擎(七)高可用