版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
Python
編程學(xué)習(xí)筆記
目錄
第一部分Python語(yǔ)言9
第1章基本環(huán)境10
1.1虛擬機(jī)10
1.2類型和對(duì)象10
1.3名字空間12
1.4內(nèi)存管理14
1.5編譯20
1.6執(zhí)行22
第2章內(nèi)置類型24
2.1數(shù)字24
2.2字符串27
2.3列表33
2.4元組35
2.5字典36
2.6集合41
第3章表達(dá)式45
3.1句法規(guī)則45
3.2命名規(guī)則47
3.3賦值48
3.4表達(dá)式49
3.5運(yùn)算符54
3.6類型轉(zhuǎn)換58
3.7常用函數(shù)58
第4章函數(shù)61
4
4.1創(chuàng)建61
4.2參數(shù)62
4.3作用域64
4.4閉包69
4.5堆棧幀71
4.6包裝73
第5章迭代器74
5.1迭代器74
5.2生成器75
5.3模式77
5.4寶藏79
第6章模塊84
6.1模塊對(duì)象84
6.2搜索路徑85
6.3導(dǎo)入模塊86
6.4構(gòu)建包89
第7章類93
7.1名字空間93
7.2字段94
7.3屬性96
7.4方法99
7.5繼承102
7.6開(kāi)放類109
7.7操作符重載112
第8章異常116
8.1異常116
5
8.2斷言118
8.3上下文118
第9章裝飾器122
第10章描述符128
第11章元類132
第二部分標(biāo)準(zhǔn)庫(kù)136
第12章字符串137
12.1re137
12.2StringIO143
12.3struct143
第13章數(shù)據(jù)類型145
13.1bisect145
13.2heapq146
第14章數(shù)學(xué)運(yùn)算149
14.1random149
第15章文件與皿錄152
15.1file152
15.2binary153
15.3encoding154
15.4descriptor154
15.5tempfile155
15.6os.path156
15.7os158
15.8shutil160
第16章數(shù)據(jù)存儲(chǔ)161
16.1serialization161
6
16.2shevle163
第17章數(shù)據(jù)壓縮164
第18章格式解析165
第19章數(shù)據(jù)加密166
第20章操作系統(tǒng)167
20.1time167
20.2threading169
20.3multiprocessing174
20.4argparse179
20.5ctypes186
第21章進(jìn)程通信188
21.1subprocess188
22.2signal189
第22章絡(luò)編程192
第23章程序框架193
23.1cmd193
23.2shlex194
第24章開(kāi)發(fā)工具196
第25章運(yùn)行時(shí)服務(wù)197
第26章語(yǔ)言服務(wù)198
第三部分?jǐn)U展庫(kù)199
A.Fabric200
附錄203
A.CPython204
B.IPython205
7
C.PDB207
D.PIP-install208
E.VirtualEnv209
8
第一部分Python語(yǔ)言
Python2.7語(yǔ)言相關(guān)
9
第1章基本環(huán)境
1.1虛擬機(jī)
Python是一種半編譯半解釋型運(yùn)行環(huán)境。首先,它會(huì)在模塊"載入"時(shí)將源碼編譯成字節(jié)碼(Byte
Code)o而后,這些字節(jié)碼會(huì)被虛擬機(jī)在一個(gè)“巨大”的核心函數(shù)里解釋執(zhí)行。這是導(dǎo)致Python性
能較低的重要原因,好在現(xiàn)在有了內(nèi)置Just-in-time二次編譯器的PvPv可供選擇。
當(dāng)虛擬機(jī)開(kāi)始運(yùn)行時(shí),它通過(guò)初始化函數(shù)完成整個(gè)運(yùn)行環(huán)境設(shè)置:
?創(chuàng)建解釋器和主線程狀態(tài)對(duì)象,這是整個(gè)進(jìn)程的根對(duì)象。
?初始化內(nèi)置類型。數(shù)字、列表等類型都有專的緩存策略需要處理。
?創(chuàng)建_bui田n_模塊,該模塊持有所有內(nèi)置類型和函數(shù)。
?創(chuàng)建sys模塊,其中包含了sys.path、modules等重要的運(yùn)行期信息。
?初始化import機(jī)制。
?初始化內(nèi)置Exceptiono
?創(chuàng)建_main_模塊,準(zhǔn)備運(yùn)行所需的名字空間。
?通過(guò)s讓e.py將s讓e-packages中的第三方擴(kuò)展庫(kù)添加到搜索路徑列表。
?執(zhí)行入口py文件。執(zhí)行前會(huì)將_main.dict_作為名字空間傳遞進(jìn)去。
?程序執(zhí)行結(jié)束。
?執(zhí)行清理操作,包括調(diào)用退出函數(shù),GC清理現(xiàn)場(chǎng),釋放所有模塊等。
?終止進(jìn)程。
Python源碼是個(gè)寶庫(kù),其中有大量的編程范式和技巧可供借鑒,尤其是對(duì)內(nèi)存的管理分配。個(gè)人
建議有C基礎(chǔ)的兄弟,在閑暇時(shí)翻看一二。
1.2類型和對(duì)象
先有類型(Type),而后才能生成實(shí)例(Instance)。Python中的一切都是對(duì)象,包括類型在內(nèi)的每
個(gè)對(duì)象都包含一個(gè)標(biāo)準(zhǔn)頭,通過(guò)頭部信息就可以明確知道其具體類型。
頭信息由“引用計(jì)數(shù)"和“類型指針”組成,前者在對(duì)象被引用時(shí)增加,超出作用域或手工釋放后減
小,等于0時(shí)會(huì)被虛擬機(jī)回收(某些被緩存的對(duì)象計(jì)數(shù)器永遠(yuǎn)不會(huì)為0)。
以int為例,對(duì)應(yīng)Python結(jié)構(gòu)定義是:
#definePyObject_HEAD\
Py_ssize_tob_refcnt;\
structJypeobject*ob_type;
typedefstruct_object{
PyObject_HEAD
10
}PyObject;
typedefstruct{
PyObject_HEAD〃在64位版本中,頭度為16字節(jié)。
longobjval;//long是8字節(jié)。
}PylntObject;
可以用sys中的函數(shù)測(cè)試一下。
?>importsys
?>x=0x1234#不要使用卜5,257)之間的小數(shù)字,它們有專的緩存機(jī)制。
?>sys.getsizeof(x)#符合度預(yù)期。
24
?>sys.getrefcount(x)#sys.getrefcount()讀取頭部引用計(jì)數(shù),注意形參也會(huì)增加一次引用。
2
>?y=x#引用計(jì)數(shù)增加。
?>sys.getrefcount(x)
3
?>dely#引用計(jì)數(shù)減小。
?>sys.getrefcount(x)
2
類型指針則指向具體的類型對(duì)象,其中包含了繼承關(guān)系、靜態(tài)成員等信息。所有的內(nèi)置類型對(duì)象都
能從types模塊中找到,至于int、long、str這些關(guān)鍵字可以看做是簡(jiǎn)短別名。
?>importtypes
?>x=20
?>type(x)istypes.lntType#is通過(guò)指針判斷是否指向同一對(duì)象。
True
>?x._class—#_class_通過(guò)類型指針來(lái)獲取類型對(duì)象。
<type'int'>
?>x._class_istype(x)isintistypes.lntType
True
?>y=x
?>hex(id(x))5hex(id(y))#id()返回對(duì)象標(biāo)識(shí),其實(shí)就是內(nèi)存地址。
('0x7fc5204103c0','0x7fc5204103c0,)
11
?>hex(id(int)),hex(id(types.lntType))
('0x1088cebd8','0x1088cebd8')
除了int這樣的固定度類型外,還有l(wèi)ong、str這類變對(duì)象。其頭部多出一個(gè)記錄元素項(xiàng)數(shù)量
的字段。比如str的字節(jié)數(shù)量,list列表的度等等。
#definePyObject_VAR_HEAD\
PyObject_HEAD\
Py_ssize_tob_size;/*Numberofitemsinvariablepart*/
typedefstruct{
PyObject_VAR_HEAD
}PyVarObject;
有關(guān)類型和對(duì)象更多的信息,將在后續(xù)章節(jié)中詳述。
1.3名字空間
名字空間是Python最核心的內(nèi)容。
?>X
NameError:name'x'isnotdefined
我們習(xí)慣于將X稱為變量,但在這里,更準(zhǔn)確的詞語(yǔ)是“名字”。
和C變量名是內(nèi)存地址別名不同,Python的名字實(shí)際上是一個(gè)字符串對(duì)象,它和所指向的皿標(biāo)對(duì)
象一起在名字空間中構(gòu)成一項(xiàng){name:object}關(guān)聯(lián)。
Python有多種名字空間,比如稱為globals的模塊名字空間,稱為locals的函數(shù)堆棧幀名字空
間,還有class、instance名字空間。不同的名字空間決定了對(duì)象的作用域和生存周期。
?>x=123
?>globals()#獲取module名字空間。
{'X':123,……}
可以看出,名字空間就是一個(gè)字典(diet)。我們完全可以直接在名字空間添加項(xiàng)來(lái)創(chuàng)建名字。
?>globals()["y"]="Hello,World!"
?>y
'Hello,World!'
在Python源碼中,有這樣一句話:Nameshavenotype,butobjectsdo.
12
名字的作用僅僅是在某個(gè)時(shí)刻與名字空間中的某個(gè)對(duì)象進(jìn)行關(guān)聯(lián)。其本身不包含皿標(biāo)對(duì)象的任何信
息,只有通過(guò)對(duì)象頭部的類型指針才能獲知其具體類型,進(jìn)而查找其相關(guān)成員數(shù)據(jù)。正因?yàn)槊值?/p>
弱類型特征,我們可以在運(yùn)行期隨時(shí)將其關(guān)聯(lián)到任何類型對(duì)象。
?>y
'Hello,World!'
?>type(y)
<type'str'>
?>y=_import_(”string”)#將原本與字符串關(guān)聯(lián)的名字指向模塊對(duì)象。
?>type(y)
<type'modules
?>y.digits#查看模塊對(duì)象的成員。
,0123456789,
在函數(shù)外部,locals。和globals。作用完全相同。而當(dāng)在函數(shù)內(nèi)部調(diào)用時(shí),locals。則是獲取當(dāng)前
函數(shù)堆棧幀的名字空間,其中存儲(chǔ)的是函數(shù)參數(shù)、局部變量等信息。
?>importsys
?>globals()islocals()
True
?>locals()
(
,—builtins_<module'_builtin—'(built-in)>,
'_name__main_
'sys':<module'sys'(built-in)>,
)
?>deftest(x):#請(qǐng)對(duì)比下面的輸出內(nèi)容。
...y=x+100
...printlocals()#可以看到locals名字空間中包含當(dāng)前局部變量。
…printglobals()islocals()#此時(shí)locals和globals指向不同名字空間。
...frame=sys._getframe(O)#_getframe(O)獲取當(dāng)前堆棧幀。
■■■printlocals()isframe.fjocals#locals名字空間實(shí)際就是當(dāng)前堆棧幀的名字空間。
...printglobals()isframe.f_globals#通過(guò)什ame我們也可以函數(shù)定義模塊的名字空間。
?>test(123)
{'y':223,'x':123}
False
True
True
13
在函數(shù)中調(diào)用globals()時(shí),總是獲取包含該函數(shù)定義的模塊名字空間,而非調(diào)用處。
?>pycattest.py
a=1
deftest():
print{k:vfork,vinglobals().items()ifk!="_builtins_"}
?>importtest
?>test.test()
(
'file—'test.pyc',
'—name—'test',
'a':1,
'test':<functiontestat0x10bd85e60>,
可通過(guò)〈module〉.—diet—訪問(wèn)其他模塊的名字空間。
?>test._diet_#test模塊的名字空間
{
1file_'test.pyc",
'—name—'test',
'a':1,
'test':<functiontestat0x10bd85e60>,
}
?>importsys
?>sys.modules[_name_]._diet_isglobals()#當(dāng)前模塊名字空間和globals相同。
True
與名字空間有關(guān)的內(nèi)容很多,比如作用域、LEGB查找規(guī)則、成員查找規(guī)則等等。所有這些,都將
在相關(guān)章節(jié)中給出詳細(xì)說(shuō)明。
使用名字空間管理上下文對(duì)象,帶來(lái)無(wú)與倫比的靈活性,但也犧牲了執(zhí)行性能。畢竟從字典中查找
對(duì)象遠(yuǎn)比指針低效很多,各有得失。
1.4內(nèi)存管理
為提升執(zhí)行性能,Python在內(nèi)存管理上做了大量工作。最直接的做法就是用內(nèi)存池來(lái)減少操作系
統(tǒng)內(nèi)存分配和回收操作,那些小于等于256字節(jié)對(duì)象,將直接從內(nèi)存池中獲取存儲(chǔ)空間。
根據(jù)需要,虛擬機(jī)每次從操作系統(tǒng)申請(qǐng)一塊256KB,取名為arena的大塊內(nèi)存。并按系統(tǒng)大
小,劃分成多個(gè)pool。每個(gè)pool繼續(xù)分割成n個(gè)大小相同的block,這是內(nèi)存池最小存儲(chǔ)單位。
14
block大小是8的倍數(shù),也就是說(shuō)存儲(chǔ)13字節(jié)大小的對(duì)象,需要找block大小為16的pool獲
取空閑塊。所有這些都用頭信息和鏈表管理起來(lái),以便快速查找空閑區(qū)域進(jìn)行分配。
大于256字節(jié)的對(duì)象,直接用malloc在堆上分配內(nèi)存。程序運(yùn)行中的絕大多數(shù)對(duì)象都小于這個(gè)閾
值,因此內(nèi)存池策略可有效提升性能。
當(dāng)所有arena的總?cè)萘砍鱿拗?64MB)時(shí),就不再請(qǐng)求新的arena內(nèi)存。而是如同“大對(duì)象"一
樣,直接在堆上為對(duì)象分配內(nèi)存。另外,完全空閑的arena會(huì)被釋放,其內(nèi)存交還給操作系統(tǒng)。
引用傳遞
對(duì)象總是按引用傳遞,簡(jiǎn)單點(diǎn)說(shuō)就是通過(guò)復(fù)制指針來(lái)實(shí)現(xiàn)多個(gè)名字指向同一對(duì)象。因?yàn)閍rena也是
在堆上分配的,所以無(wú)論何種類型何種大小的對(duì)象,都存儲(chǔ)在堆上。Python沒(méi)有值類型和引用類
型一說(shuō),就算是最簡(jiǎn)單的整數(shù)也是擁有標(biāo)準(zhǔn)頭的完整對(duì)象。
?>a=object()
?>b=a
?>aisb
True
>?hex(id(a))5hex(id(b))#地址相同,意味著對(duì)象是同一個(gè)。
('0x10b1f5640','0x10b1f5640')
?>deftest(x):
...printhex(id(x))
?>test(a)
0x10b1f5640#地址依舊相同。
如果不希望對(duì)象被修改,就需使用不可變類型,或?qū)ο髲?fù)制品。
不可變類型:int,long,str,tuple,frozenset
除了某些類型自帶的copy方法外,還可以:
?使用標(biāo)準(zhǔn)庫(kù)的copy模塊進(jìn)行深度復(fù)制。
?序列化對(duì)象,如pickle、cPickle、marshal0
下面的測(cè)試建議不要用數(shù)字等不可變對(duì)象,因?yàn)槠鋬?nèi)部的緩存和復(fù)用機(jī)制可能會(huì)造成干擾。
?>importcopy
?>x=object()
?>l=[x]#創(chuàng)建一個(gè)列表。
15
?>12=copy.copy(l)#淺復(fù)制,僅復(fù)制對(duì)象自身,而不會(huì)遞歸復(fù)制其成員。
?>12isI#可以看到復(fù)制列表的元素依然是原對(duì)象。
False
?>12[0]isx
True
?>13=copy.deepcopy(l)#深度復(fù)制,會(huì)遞歸復(fù)制所有深度成員。
?>13isI#列表元素也被復(fù)制了。
False
?>13[0]isx
False
循環(huán)引用會(huì)影響deepcopy函數(shù)的運(yùn)作,建議查閱官方標(biāo)準(zhǔn)庫(kù)文檔。
引用計(jì)數(shù)
Python默認(rèn)采用引用計(jì)數(shù)來(lái)管理對(duì)象的內(nèi)存回收。當(dāng)引用計(jì)數(shù)為0時(shí),將立即回收該對(duì)象內(nèi)存,
要么將對(duì)應(yīng)的block塊標(biāo)記為空閑,要么返還給操作系統(tǒng)。
為觀察回收行為,我們用—del_監(jiān)控對(duì)象釋放。
?>classUser(object):
...def_del—(self):
...print"Willbedead!"
?>a=User()
?>b=a
?>importsys
?>sys.getrefcount(a)
3
?>dela#刪除引用,計(jì)數(shù)減小。
?>sys.getrefcount(b)
2
?>delb#刪除最后一個(gè)引用,計(jì)數(shù)器為0,對(duì)象被回收。
Willbedead!
某些內(nèi)置類型,比如小整數(shù),因?yàn)榫彺娴木壒?,?jì)數(shù)永遠(yuǎn)不會(huì)為0,直到進(jìn)程結(jié)束才由虛擬機(jī)清理
函數(shù)釋放。
除了直接引用外,Python還支持弱引用。允許在不增加引用計(jì)數(shù),不妨礙對(duì)象回收的情況下間接
引用對(duì)象。但不是所有類型都支持弱引用,比如list、diet,弱引用會(huì)引發(fā)異常。
16
改用弱引用回調(diào)監(jiān)控對(duì)象回收。
?>importsys,weakref
?>classUser(object):pass
?>defcallback(r):#回調(diào)函數(shù)會(huì)在原對(duì)象被回收時(shí)調(diào)用。
...print"weakrefobject:",r
...print"targetobjectdead!"
?>a=User()
?>r=weakref.ref(a,callback)#創(chuàng)建弱引用對(duì)象。
?>sys.getrefcount(a)#可以看到弱引用沒(méi)有導(dǎo)致皿標(biāo)對(duì)象引用計(jì)數(shù)增加。
2#計(jì)數(shù)2是因?yàn)間etrefcount形參造成的。
?>r()isa#透過(guò)弱引用可以訪問(wèn)原對(duì)象。
True
?>dela#原對(duì)象回收,callback被調(diào)用。
weakrefobject:<weakrefat0x10f99a368;dead>
targetobjectdead!
?>hex(id(r))#通過(guò)對(duì)比,可以看到callback參數(shù)是弱引用對(duì)象。
'0x1Of99a368'#因?yàn)樵瓕?duì)象已經(jīng)死亡。
?>r()isNone#此時(shí)弱引用只能返回None0也可以此判斷原對(duì)象死亡。
True
引用計(jì)數(shù)是一種簡(jiǎn)單直接,并且十分高效的內(nèi)存回收方式。大多數(shù)時(shí)候它都能很好地工作,除了循
環(huán)引用造成計(jì)數(shù)故障。簡(jiǎn)單明顯的循環(huán)引用,可以用弱引用打破循環(huán)關(guān)系。但在實(shí)際開(kāi)發(fā)中,循環(huán)
引用的形成往往很復(fù)雜,可能由n個(gè)對(duì)象間接形成一個(gè)大的循環(huán)體,此時(shí)只有靠GC去回收了。
垃圾回收
事實(shí)上,Python擁有兩套垃圾回收機(jī)制。除了引用計(jì)數(shù),還有個(gè)專處理循環(huán)引用的GCo通常我
們提到垃圾回收時(shí),都是指這個(gè)"ReferenceCycleGarbageCollection"0
能引發(fā)循環(huán)引用問(wèn)題的,都是那種容器類對(duì)象,比如list、set、object等。對(duì)于這類對(duì)象,虛擬
機(jī)在為其分配內(nèi)存時(shí),會(huì)額外添加用于追蹤的PyGCJHead。這些對(duì)象被添加到特殊鏈表里,以便
GC進(jìn)行管理。
typedefunion_gc_head{
struct{
union_gc_head*gc_next;
17
union_gc_head*gc_prev;
Py_ssize_tgc_refs;
}gc;
longdoubledummy;
}PyGC_Head;
當(dāng)然,這并不表示此類對(duì)象非得GC才能回收。如果不存在循環(huán)引用,自然是積極性更高的引用計(jì)
數(shù)機(jī)制搶先給處理掉。也就是說(shuō),只要不存在循環(huán)引用,理論上可以禁用GC。當(dāng)執(zhí)行某些密集運(yùn)
算時(shí),臨時(shí)關(guān)掉GC有助于提升性能。
?>importgc
?>classUser(object):
...def_del—(self):
.printhex(id(self)),"w川bedead!"
?>gc.disable()#關(guān)掉GC
?>a=User()
?>dela#對(duì)象正?;厥?,引用計(jì)數(shù)不會(huì)依賴GCo
0x10fddf590willbedead!
同.NET、JAVA一樣,PythonGC同樣將要回收的對(duì)象分成3級(jí)代齡。GEN0管理新近加入的年
輕對(duì)象,GEN1則是在上次回收后依然存活的對(duì)象,剩下GEN2存儲(chǔ)的都是生命周期極的家伙。
每級(jí)代齡都有一個(gè)最大容量閾值,每次GEN0對(duì)象數(shù)量超出閾值時(shí),都將引發(fā)垃圾回收操作。
#defineNUM_GENERATIONS3
/*linkedlistsofcontainerobjects7
staticstructgc_generationgenerations[NUM_GENERATIONS]={
/*PyGC_Head,threshold,count*/
{{{GEN_HEAD(0),GEN_HEAD(0),0}},700,0).
{{{GENJHEAD⑴,GEN_HEAD(1),0}},10,0}.
{{{GEN_HEAD(2),GEN_HEAD(2),0}},10,0).
);
GC首先檢查GEN2,如閾值被突破,那么合并GEN2、GEN1、GEN0幾個(gè)追蹤鏈表。如果沒(méi)有超
出,則檢查GENLGC將存活的對(duì)象提升代齡,而那些可回收對(duì)象則被打破循環(huán)引用,放到專
的列表等待回收。
?>gc.get_threshold()#獲取各級(jí)代齡閾值
(700,10,10)
?>gc.get_count()#各級(jí)代齡鏈表跟蹤的對(duì)象數(shù)量
(203,0,5)
包含—del_方法的循環(huán)引用對(duì)象,永遠(yuǎn)不會(huì)被GC回收,直至進(jìn)程終止。
18
這回不能偷懶用—del—監(jiān)控對(duì)象回收了,改用weakrefo因IPython對(duì)GC存在干擾,下面的測(cè)
試代碼建議在原生shell中進(jìn)行。
?>importgc,weakref
?>classUser(object):pass
?>defcallback(r):printr,"dead"
?>gc.disable()#停掉GC,看看引用計(jì)數(shù)的能力。
?>a=User();wa=weakref.ref(a,callback)
?>b=User();wb=weakref.ref(b,callback)
?>a.b=b;b.a=a#形成循環(huán)引用關(guān)系。
?>dela;delb#刪除名字引用。
?>wa(),wb()#顯然,計(jì)數(shù)機(jī)制對(duì)循環(huán)引用無(wú)效。
(<_main_.Userobjectat0x1045f4f50>,<_main_.Userobjectat0x1045f4f90>)
?>gc.enable()#開(kāi)啟GCo
?>gc.isenabled()#可以用isenabled確認(rèn)。
True
?>gc.collect()#因?yàn)闆](méi)有達(dá)到閾值,我們手工啟動(dòng)回收。
<weakrefat0x1045a8cb0;dead>dead#GC的確有對(duì)付基友的能力。
<weakrefat0x1045a8db8;dead>dead#這個(gè)地址是弱引用對(duì)象的,別犯糊涂。
一旦有了_del_,GC就拿循環(huán)引用沒(méi)辦法了。
?>importgc,weakref
?>classUser(object):
...def_del_(self):pass#難道連空的_del_也不行?
?>defcallback(r):printr,"dead!"
?>gc.set_debug(gc.DEBUG_STATS|gc.DEBUG_LEAK)#輸出更詳細(xì)的回收狀態(tài)信息。
?>gc.isenabled()#確保GC在工作。
True
?>a=User();wa=weakref.ref(a,callback)
?>b=User();wb=weakref.ref(b,callback)
?>a.b=b;b.a=a
?>dela;delb
?>gc.collect()#從輸出信息看,回收失敗。
gc:collectinggeneration2...
19
gc:objectsineachgeneration:52031900
gc:uncollectable<User0x10fd51fd0>#a
gc:uncollectable<User0x10fd57050>#b
gc:uncollectable<dict0x7f990ac88280>#a._diet.
gc:uncollectable<dict0x7f990ac88940>#b._diet.
gc:done,4unreachable,4uncollectable,0.0014selapsed.
4
?>xa=wa()
?>xa,hex(id(xa.—diet))
<_main_.Userobjectat0x10fd51fd0>,'0x7f990ac88280,,
?>xb=wb()
?>xb,hex(id(xb.—diet))
<_main_.Userobjectat0x10fd57050>,'0x7f990ac88940'
關(guān)于用不用_del_的爭(zhēng)論很多。大多數(shù)人的結(jié)論是堅(jiān)決抵制,諸多“牛人”也是這樣教導(dǎo)新手的。
可畢竟_del_承擔(dān)了析構(gòu)函數(shù)的角色,某些時(shí)候還是有其特定的作用的。用弱引用回調(diào)會(huì)造成邏
輯分離,不便于維護(hù)。對(duì)于一些簡(jiǎn)單的腳本,我們還是能保證避免循環(huán)引用的,那不妨試試。就像
前面例子中用來(lái)監(jiān)測(cè)對(duì)象回收,就很方便。
1.5編譯
Python實(shí)現(xiàn)了棧式虛擬機(jī)(Stack-BasedVM)架構(gòu),通過(guò)與機(jī)器無(wú)關(guān)的字節(jié)碼來(lái)實(shí)現(xiàn)跨平臺(tái)執(zhí)行
能力。這種字節(jié)碼指令集沒(méi)有寄存器,完全以棧(抽象層面)進(jìn)行指令運(yùn)算。盡管很簡(jiǎn)單,但對(duì)普通
開(kāi)發(fā)人員而言,是無(wú)需關(guān)心的細(xì)節(jié)。
要運(yùn)行Python語(yǔ)言編寫(xiě)的程序,必須將源碼編譯成字節(jié)碼。通常情況下,編譯器會(huì)將源碼轉(zhuǎn)換成
字節(jié)碼后保存在pyc文件中。還可用Q參數(shù)生成py。格式,這是簡(jiǎn)單優(yōu)化后的pyc文件。
編譯發(fā)生在模塊載入那一刻。具體來(lái)看,又分為pyc和py兩種情況。
載入pyc流程:
?核對(duì)文件Magic標(biāo)記。
?檢查時(shí)間戳和源碼文件修改時(shí)間是否相同,以確定是否需要重新編譯。
?載入模塊。
如果沒(méi)有pyc,那么就需要先完成編譯:
?對(duì)源碼進(jìn)行AST分析。
?將分析結(jié)果編譯成PyCodeObjecto
?將Magic、源碼文件修改時(shí)間、PyCodeObject保存到pyc文件中。
?載入模塊。
20
Magic是一個(gè)特殊的數(shù)字,由Python版本號(hào)計(jì)算得來(lái),作為pyc文件和Python版本檢查標(biāo)記。
PyCodeObject則包含了代碼對(duì)象的完整信息。
typedefstruct{
PyObject_HEAD
intco_argcount;//參數(shù)個(gè)數(shù),不包括*args,**kwargs.
intco_nlocals;//局部變量數(shù)量。
intco_stacksize;//執(zhí)行所需的??臻g。
intco_flags;〃編譯標(biāo)志,在創(chuàng)建Frame時(shí)用得著。
PyObject*co_code;//字節(jié)碼指令。
PyObject*co_consts;//常量列表。
PyObject*co_names;//符號(hào)列表。
PyObject*co_varnames;//局部變量名列表。
PyObject*co_freevars;〃閉包:引用外部函數(shù)名字列表。
PyObject*co_cellvars;〃閉包:被內(nèi)部函數(shù)引用的名字列表。
PyObject*co_filename;//源碼文件名。
PyObject*co_name;//PyCodeObject的名字,函數(shù)名、類名什么的。
intco_firstlineno;〃這個(gè)PyCodeObject在源碼文件中的起始位置,也就是行號(hào)。
PyObject*co_lnotab;//字節(jié)碼指令偏移量和源碼行號(hào)的對(duì)應(yīng)關(guān)系,反匯編時(shí)用得著。
void*co_zombieframe;〃為優(yōu)化準(zhǔn)備的特殊Frame對(duì)象。
PyObject*co_weakreflist;〃為弱引用準(zhǔn)備的…
}PyCodeObject;
無(wú)論是模塊還是其內(nèi)部的函數(shù),都被編譯成PyCodeObject對(duì)象。內(nèi)部成員都嵌套到co_consts
列表中。
?>pycattest.py
Hello,World!
defadd(a,b):
returna+b
c=add(10,20)
?>code=compile(open("test.pyn).read(),"test.py","exec")
?>code.co_filename,code.co_name,code.co_names
('test.py',,<module>,,fdoc_'add','c'))
?>code.co_consts
(1\nHello,World!\n',<codeobjectaddat0x105b76e30,file"test.py",line5>,10,
20,None)
?>add=code.co_consts[1]
?>add.co_varnames
21
除了內(nèi)置compile函數(shù),標(biāo)準(zhǔn)庫(kù)里還有py_compile>compileall可供選擇。
?>importpy_compile,compileall
?>py_pile("test.py","test.pyo")
>?Is
main.py*test.pytest.pyo
?>pile_dir(".",0)
Listing
Compiling./main.py..
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- GB/T 21551.2-2024家用和類似用途電器的抗菌、除菌、凈化功能第2部分:抗菌材料的特殊要求
- GB/T 30843.2-20241 kV以上不超過(guò)35 kV的通用變頻調(diào)速設(shè)備第2部分:試驗(yàn)方法
- 2024高速公路工程結(jié)構(gòu)設(shè)計(jì)與施工合同3篇
- 二零二五年車輛融資租賃購(gòu)車合同模板(含車輛品牌置換)3篇
- 二零二五年度無(wú)人駕駛技術(shù)研發(fā)合同簡(jiǎn)易執(zhí)行版2篇
- 2025年新型建筑旋挖樁基勞務(wù)分包施工質(zhì)量保證合同2篇
- 買賣門(mén)市合同協(xié)議書(shū)范本2篇
- 2025年建筑施工團(tuán)隊(duì)合作協(xié)議3篇
- 二零二五版進(jìn)口貨物CIF和FOB價(jià)格條款服務(wù)合同2篇
- 二零二五年音樂(lè)節(jié)DJ藝人聘用及保障協(xié)議3篇
- 青島版(五年制)四年級(jí)下冊(cè)小學(xué)數(shù)學(xué)全冊(cè)導(dǎo)學(xué)案(學(xué)前預(yù)習(xí)單)
- 退學(xué)費(fèi)和解協(xié)議書(shū)模板
- 2024至2030年中國(guó)對(duì)氯甲苯行業(yè)市場(chǎng)全景調(diào)研及發(fā)展趨勢(shì)分析報(bào)告
- 智能教育輔助系統(tǒng)運(yùn)營(yíng)服務(wù)合同
- 心功能分級(jí)及護(hù)理
- DLT 572-2021 電力變壓器運(yùn)行規(guī)程
- 重慶育才中學(xué)2025屆化學(xué)九上期末教學(xué)質(zhì)量檢測(cè)試題含解析
- 成都市2022級(jí)(2025屆)高中畢業(yè)班摸底測(cè)試(零診)數(shù)學(xué)試卷(含答案)
- 【云南省中藥材出口現(xiàn)狀、問(wèn)題及對(duì)策11000字(論文)】
- 服裝板房管理制度
- 河北省興隆縣盛嘉恒信礦業(yè)有限公司李杖子硅石礦礦山地質(zhì)環(huán)境保護(hù)與治理恢復(fù)方案
評(píng)論
0/150
提交評(píng)論