參考:
- python內存管理機制,gc機制的了解,gc回收三種算法。
- lambda函數
- 高級函數 map、reduce、filter、sorted等。
- 簡述六種基本數據類型(number、string、list、tuple、dict、set)。
- python中深拷貝與淺拷貝。
- python中is和==的區別。
- python中if __ name ==' main __'有什么含義?
- python命令和python -m命令在執行腳本時的區別?
- python中多進程、多線程、協程。
- python中迭代器、生成器。
- python中裝飾器。
- python中單引號、雙引號、三引號的應用場景與區別。
- python如何體現面對對象的三大特性。
- python中異常管理的機制。
- python函數閉包。
python內存管理機制,gc機制的了解,gc回收三種算法。
python內存管理(原博文——python內存管理)
python是動態語言,對象與引用分類,一個變量使用不需要事先聲明,而在賦值時,變量可以重新賦值為任意值。
python中,整數和短小的字符,Python都會緩存這些對象,以便重復使用。當我們創建多個等於1的引用時,實際上是讓所有這些引用指向同一個對象。(可以通過is判斷是不是同一個對象)
在python中,每個對象都有存有指向該對象的引用總數,即引用計數(reference count)。我們可以使用sys包中的getrefcount(),來查看某個對象的引用計數。需要注意的是,當使用某個引用作為參數,傳遞給getrefcount()時,參數實際上創建了一個臨時的引用。因此,getrefcount()所得到的結果,會比期望的多1。
python的一個容器對象(container),比如表、詞典等,可以包含多個對象。實際上,容器對象中包含的並不是元素對象本身,是指向各個元素對象的引用。
python中對象可以引用對象,對象的相互引用會構成引用環。
引用減少的情況:1. del刪除某一個對象的引用;2. 如果某個引用指向對象A,當這個引用重新被定義到其他對象時,引用數減少。
python垃圾回收
從基本原理上,當Python的某個對象的引用計數降為0時,說明沒有任何引用指向該對象,該對象就成為要被回收的垃圾了。但是,垃圾回收時,Python不能進行其它的任務。頻繁的垃圾回收將大大降低Python的工作效率。如果內存中的對象不多,就沒有必要總啟動垃圾回收。所以,Python只會在特定條件下,自動啟動垃圾回收。當Python運行時,會記錄其中分配對象(object allocation)和取消分配對象(object deallocation)的次數。當兩者的差值高於某個閾值時,垃圾回收才會啟動。
我們可以通過gc模塊的get_threshold()方法,查看該閾值:
import gc print(gc.get_threshold())
返回(700, 10, 10),后面的兩個10是與分代回收相關的閾值,后面可以看到。700即是垃圾回收啟動的閾值。可以通過gc中的set_threshold()方法重新設置。我們也可以手動啟動垃圾回收,即使用gc.collect()。
分代回收: python同時采用了分代(generation)回收的策略。這一策略的基本假設是,存活時間越久的對象,越不可能在后面的程序中變成垃圾。我們的程序往往會產生大量的對象,許多對象很快產生和消失,但也有一些對象長期被使用。出於信任和效率,對於這樣一些“長壽”對象,我們相信它們的用處,所以減少在垃圾回收中掃描它們的頻率。python將所有的對象分為0,1,2三代。所有的新建對象都是0代對象。當某一代對象經歷過垃圾回收,依然存活,那么它就被歸入下一代對象。垃圾回收啟動時,一定會掃描所有的0代對象。如果0代經過一定次數垃圾回收,那么就啟動對0代和1代的掃描清理。當1代也經歷了一定次數的垃圾回收后,那么會啟動對0,1,2,即對所有對象進行掃描。這兩個次數即上面get_threshold()返回的(700, 10, 10)返回的兩個10。也就是說,每10次0代垃圾回收,會配合1次1代的垃圾回收;而每10次1代的垃圾回收,才會有1次的2代垃圾回收。同樣可以用set_threshold()來調整,比如對2代對象進行更頻繁的掃描。
孤立的引用環: 引用環的存在會給上面的垃圾回收機制帶來很大的困難。這些引用環可能構成無法使用,但引用計數不為0的一些對象。比如我們創建了兩個表對象,並引用對方,構成一個引用環。刪除了a,b引用之后,這兩個對象不可能再從程序中調用,就沒有什么用處了。但是由於引用環的存在,這兩個對象的引用計數都沒有降到0,不會被垃圾回收。
a = [] b = [a] a.append(b) del a del b
為了回收這樣的引用環,python復制每個對象的引用計數,可以記為gc_ref。假設,每個對象i,該計數為gc_ref_i。python會遍歷所有的對象i。對於每個對象i引用的對象j,將相應的gc_ref_j減1。在結束遍歷后,gc_ref不為0的對象,和這些對象引用的對象,以及繼續更下游引用的對象,需要被保留。而其它的對象則被垃圾回收。
lambda函數
lambda作為一個表達式,定義了一個匿名函數。lambda表達式是起到一個函數速寫的作用,允許在代碼內嵌入一個函數的定義。例如:
func1 = lambda x,y:x+y def func2(x,y): return x+y
func1和func2其實作用相同。
lambda的優點是代碼比較簡潔,缺點是易讀性不好。
高級函數 map、reduce、filter、sorted等。
map()
map() 會根據提供的函數對指定序列做映射。第一個參數 function 以參數序列中的每一個元素調用 function 函數,返回包含每次 function 函數返回值的新列表。
map(function, iterable,...)
返回值:python 2.x返回列表,python3.x返回迭代器。
以python3為例:
a = map(lambda x:x**2,[1,2,3,4]) print(a) print(list(a))
輸出:
<map object at 0x000001EB55F4C710> [1, 4, 9, 16]
filter()
filter() 函數用於過濾序列,過濾掉不符合條件的元素,返回一個迭代器對象,如果要轉換為列表,可以使用 list() 來轉換。
該接收兩個參數,第一個為函數,第二個為序列,序列的每個元素作為參數傳遞給函數進行判,然后返回 True 或 False,最后將返回 True 的元素放到新列表中。
# 第一個參數是判斷函數,第二個參數是可迭代對象 filter(function, iterable)
實例:
a = filter(lambda x:x%2==0,[1,2,3,4]) print(a) print(list(a))
輸出:
<filter object at 0x000001EB55F44F60> [2, 4]
reduce()
reduce()函數也是Python內置的一個高階函數。reduce()函數接收的參數和 map()類似,一個函數 function,一個可迭代對象,但行為和 map()不同,reduce()傳入的函數必須接收兩個參數,reduce()對list的每個元素反復調用函數f,並返回最終結果值。
在python3中,reduce()函數已經從全局函數中移除了,放在fucntools,所以我們首先得導入從fucntools中導入reduce()函數。
reduce(function, iterable)
實例:
from functools import reduce sum = reduce(lambda x,y:x+y,[1,3,5,7,9]) print(sum)
輸出:
25
sorted()
sorted() 函數對所有可迭代的對象進行排序操作。
sort與sorted的區別:
sort 是應用在 list 上的方法,sorted 可以對所有可迭代的對象進行排序操作。
list 的 sort 方法返回的是對已經存在的列表進行操作,而內建函數 sorted 方法返回的是一個新的 list,而不是在原來的基礎上進行的操作。
sorted(iterable, key=None, reverse=False)
- iterable -- 可迭代對象。
- key -- 主要是用來進行比較的元素,只有一個參數,具體的函數的參數就是取自於可迭代對象中,指定可迭代對象中的一個元素來進行排序。
- reverse -- 排序規則,reverse = True 降序 , reverse = False 升序(默認)。
實例:
nums = [[2,1],[3,4],[5,2],[4,10]] # 將二維數組按第一列逆序排列 sorted(nums, key = lambda x:x[0], reverse = True)
輸出:
[[5, 2], [4, 10], [3, 4], [2, 1]]
簡述六種基本數據類型(number、string、list、tuple、dict、set)。
數字number菜鳥教程——python3數字
Python 支持三種不同的數值類型:
- 整型(Int) - 通常被稱為是整型或整數,是正或負整數,不帶小數點。Python3 整型是沒有限制大小的,可以當作 Long 類型使用,所以 Python3 沒有 Python2 的 Long 類型。
- 浮點型(float) - 浮點型由整數部分與小數部分組成,浮點型也可以使用科學計數法表示(2.5e2 = 2.5 x 102 = 250)
- 復數( (complex)) - 復數由實數部分和虛數部分構成,可以用a + bj,或者complex(a,b)表示, 復數的實部a和虛部b都是浮點型。
python數字類型轉換:
int(x) 將x轉換為一個整數。
float(x) 將x轉換到一個浮點數。
complex(x) 將x轉換到一個復數,實數部分為 x,虛數部分為 0。
complex(x, y) 將 x 和 y 轉換到一個復數,實數部分為 x,虛數部分為 y。x 和 y 是數字表達式。
字符串string菜鳥教程——python3字符串
創建:可以用單引號或者雙引號創建。
切片:string類型支持切片。
拼接:可以用加號拼接兩個字符串。
...(內容比較多,參考上面的鏈接)
列表list菜鳥教程——python3列表
列表是最常用的Python數據類型,它可以作為一個方括號內的逗號分隔值出現。列表的數據項不需要具有相同的類型創建一個列表,只要把逗號分隔的不同的數據項使用方括號括起來即可。
其他的參見上面的鏈接。
元組tuple菜鳥教程——python3元組
Python 的元組與列表類似,不同之處在於元組的元素不能修改。
元組使用小括號(但是訪問元組中的元素用中括號,例如:tuple[0]),列表使用方括號。元組創建很簡單,只需要在括號中添加元素,並使用逗號隔開即可。
注意:元組中只有一個元素時,需要在該元素后面加一個逗號,如下:
tuple1 = (1) tuple2 = (1,) print(type(tuple1),type(tuple2))
輸出:
<class 'int'> <class 'tuple'>
元組允許兩個元組相加得到新的元組。(tuple1 + tuple2 = tuple3)
元組中元素不能刪除,但是可以刪除整個元組。(del tuple)
元組很多方法跟列表都是互通的。
字典dict菜鳥教程——python3字典
字典是另一種可變容器模型,且可存儲任意類型對象。
字典的每個鍵值(key=>value)對用冒號(:)分割,每個對之間用逗號(,)分割,整個字典包括在花括號{}中。
鍵必須是唯一的,但值則不必。值可以取任何數據類型,但鍵必須是不可變的,如字符串,數字或元組。
字典方法很多,參見鏈接。
集合set菜鳥教程——python3集合
集合(set)是一個無序的不重復元素序列。可以使用大括號 { } 或者 set() 函數創建集合,注意:創建一個空集合必須用 set() 而不是 { },因為 { } 是用來創建一個空字典。
方法參見鏈接。
python中深拷貝與淺拷貝。
- Python中對象的賦值都是進行對象引用(內存地址)傳遞
- 使用copy.copy(),可以進行對象的淺拷貝,它復制了對象,但對於對象中的元素,依然使用原始的引用。
- 如果需要復制一個容器對象,以及它里面的所有元素(包含元素的子元素),可以使用copy.deepcopy()進行深拷貝。
- 對於非容器類型(如數字、字符串、和其他'原子'類型的對象)沒有被拷貝一說
- 如果元祖變量只包含原子類型對象,則不能深拷貝
例如:
import copy a = [1, [1,2]] b = a c = copy.copy(a) d = copy.deepcopy(a) print(b is a, c is a, d is a) print('判斷copy函數淺拷貝之后,容器內部的對象是不是地址一致:',c[1] is a[1],c[0] is a[0]) a[1][1] = 3 print(a, b, c, d)
輸出:
True False False 判斷copy函數淺拷貝之后,容器內部的對象是不是地址一致: True True [1, [1, 3]] [1, [1, 3]] [1, [1, 3]] [1, [1, 2]]
python中is和==的區別。
Python中對象包含的三個基本要素,分別是:id(身份標識)、type(數據類型)和value(值)。
==是python標准操作符中的比較操作符,用來比較判斷兩個對象的value(值)是否相等。
is也被叫做同一性運算符,這個運算符比較判斷的是對象間的唯一身份標識,也就是id是否相同。
例如:
a = [1] c = [1] print(a == c, a is c)
輸出:
True False
- 事實上Python 為了優化速度,使用了小整數對象池,避免為整數頻繁申請和銷毀內存空間。而Python 對小整數的定義是 [-5, 257),只有數字在-5到256之間它們的id才會相等,超過了這個范圍就不行了,同樣的道理,字符串對象也有一個類似的緩沖池,超過區間范圍內自然不會相等了。 總的來說,只有數值型和字符串型,並且在通用對象池中的情況下,a is b才為True,否則當a和b是int,str,tuple,list,dict或set型時,a is b均為False。
例如:
a = 2 c = 2 print(a == c, a is c)
輸出:
True True
python中if __ name ==' main __'有什么含義?
python命令和python -m命令在執行腳本時的區別?
python中多進程、多線程、協程。
python中迭代器、生成器。
迭代器:
迭代是Python最強大的功能之一,是訪問集合元素(字符串、列表、元組、集合、字典)的一種方式。迭代器是一個可以記住遍歷的位置的對象。
迭代器對象從集合的第一個元素開始訪問,直到所有的元素被訪問完結束。迭代器只能往前不會后退。(迭代器可以使用for語句進行遍歷)
迭代器有兩個基本的方法:iter() 和 next()。
實例:
a =[1, 2, 3, 4] b = iter(a) print(type(b)) while True: try: print(next(b)) except: print('over') break
輸出:
<class 'list_iterator'> 1 2 3 4 over
生成器:
在 Python 中,使用了 yield 的函數被稱為生成器(generator)。
跟普通函數不同的是,生成器是一個返回迭代器的函數,只能用於迭代操作,更簡單點理解生成器就是一個迭代器。在調用生成器運行的過程中,每次遇到 yield 時函數會暫停並保存當前所有的運行信息,返回 yield 的值, 並在下一次執行 next() 方法時從當前位置繼續運行。調用一個生成器函數,返回的是一個迭代器對象。
實例:
def helper(n): i = 0 while i<n: yield i i += 1 f = helper(5) while True: try: print(next(f)) except: print('over') break
輸出:
0 1 2 3 4 over