淺析python中特殊文件和特殊函數(shù)
導(dǎo)入模塊
模塊通常為單獨(dú)的.py文件,可以用import直接引用,可以作為模塊的文件類型有.py、.pyo、.pyc、.pyd、.so、.dll在導(dǎo)入模塊時(shí),解釋器做以下工作:
- 已導(dǎo)入模塊的名稱創(chuàng)建新的命名空間,通過該命名空間就可以訪問導(dǎo)入模塊的屬性和方法。
- 在新創(chuàng)建的命名空間中執(zhí)行源代碼文件。
- 創(chuàng)建一個(gè)名為源代碼文件的對(duì)象,該對(duì)象引用模塊的名字空間,這樣就可以通過這個(gè)對(duì)象訪問模塊中的函數(shù)及變量
import 語句可以在程序的任何位置使用,你可以在程序中多次導(dǎo)入同一個(gè)模塊,但模塊中的代碼僅僅在該模塊被首次導(dǎo)入時(shí)執(zhí)行。后面的import語句只是簡(jiǎn)單的創(chuàng)建一個(gè)到模塊名字空間的引用而已。sys.modules字典中保存著所有被導(dǎo)入模塊的模塊名到模塊對(duì)象的映射。
導(dǎo)入包
多個(gè)相關(guān)聯(lián)的模塊組成一個(gè)包,即多個(gè).py文件構(gòu)成一個(gè)包,以便于維護(hù)和使用,同時(shí)能有限的避免命名空間的沖突。一般來說,包的結(jié)構(gòu)可以是這樣的:
package |- subpackage1 |- __init__.py |- a.py |- subpackage2 |- __init__.py |- b.py
有以下幾種導(dǎo)入方式
import subpackage1.a # 將模塊subpackage.a導(dǎo)入全局命名空間,例如訪問a中屬性時(shí)用subpackage1.a.attr from subpackage1 import a # 將模塊a導(dǎo)入全局命名空間,例如訪問a中屬性時(shí)用a.attr_a from subpackage1.a import attr_a # 將模塊a的屬性直接導(dǎo)入到命名空間中,例如訪問a中屬性時(shí)直接用attr_a
使用from語句可以把模塊直接導(dǎo)入當(dāng)前命名空間,from語句并不引用導(dǎo)入對(duì)象的命名空間,而是將被導(dǎo)入對(duì)象直接引入當(dāng)前命名空間
可以被import語句導(dǎo)入的對(duì)象是以下類型:
- 模塊文件(.py文件)
- C或C++擴(kuò)展(已編譯為共享庫或DLL文件)
- 包(包含多個(gè)模塊)
- 內(nèi)建模塊(使用C編寫并已鏈接到Python解釋器中)
特殊文件
1、__init__.py文件
__init__.py
文件的作用就是將該文件所處的文件夾當(dāng)做一個(gè)模塊來管理,每當(dāng)有外部文件來import
的時(shí)候,就會(huì)執(zhí)行里面的函數(shù)
__init__.py
是怎么工作的
當(dāng)一個(gè)目錄下含有這個(gè)文件,則這個(gè)文件夾就是一個(gè)python模塊,通常__init__.py
文件為空,但是我們還可以為它增加其他的功能。我們?cè)趯?dǎo)入一個(gè)包時(shí),實(shí)際上是導(dǎo)入了它的__init__.py
文件。這樣我們可以在__init__.py
文件中批量導(dǎo)入我們所需要的模塊,而不再需要一個(gè)一個(gè)的導(dǎo)入。
當(dāng)import導(dǎo)入該模塊時(shí),同時(shí)會(huì)執(zhí)行該文件內(nèi)容,當(dāng)導(dǎo)入該模塊中的某個(gè)函數(shù)時(shí)需要加上該包名,不然就會(huì)報(bào)錯(cuò),如下,當(dāng)在其他文件中要導(dǎo)入子包subpackage_1中的test11函數(shù)時(shí),需要加上包名mypackage
from mypackage.subpackage_1 import test11
__init__.py
中還有一個(gè)重要的變量,__all__
, 它用來將模塊全部導(dǎo)入。
# __init__.py __all__ = ['os', 'sys', 're', 'urllib'] # a.py from package import *
這時(shí)就會(huì)把注冊(cè)在__init__.py
文件中__all__
列表中的模塊和包導(dǎo)入到當(dāng)前文件中來。在了解了__init__.py
的工作原理后,應(yīng)該能理解該文件就是一個(gè)正常的python代碼文件。因此可以將初始化代碼放入該文件中。
2、.pyc與 .pyo文件
.py文件在匯編時(shí),會(huì)生成.pyc文件,在匯編時(shí),會(huì)將.py文件中的import的文件鏈接起來匯編成字節(jié)碼寫到一個(gè).pyc文件中,后面執(zhí)行時(shí),就直接執(zhí)行.pyc文件,省去每次都要重新匯編,提高運(yùn)行速度,(當(dāng).py文件的修改時(shí)間發(fā)生改變,這樣會(huì)生成新的.pyc文件)在解釋器使用-O選項(xiàng)時(shí),將使用同名的.pyo文件,這個(gè)文件去掉了斷言(assert)、斷行號(hào)以及其他調(diào)試信息,體積更小,運(yùn)行更快。(使用-OO選項(xiàng),生成的.pyo文件會(huì)忽略文檔信息)
特殊函數(shù)
1、構(gòu)造函數(shù)
構(gòu)造函數(shù)是一種特殊的類成員方法,主要用在創(chuàng)建對(duì)象時(shí)初始化對(duì)象
python中的構(gòu)造函數(shù)用__init__命名
2、析構(gòu)函數(shù)
析構(gòu)函數(shù)是構(gòu)造函數(shù)的反函數(shù),在銷毀對(duì)象時(shí)調(diào)用他們,往往用來做清理善后,
例如:數(shù)據(jù)庫連接對(duì)象可以在析構(gòu)函數(shù)中釋放對(duì)數(shù)據(jù)庫實(shí)例資源的占用
python中為類定義析構(gòu)函數(shù)的方法是在類中定義一個(gè)名為__del__的沒有返回值和參數(shù)的函數(shù)
python中顯示銷毀對(duì)象的方法,使用del關(guān)鍵
3、靜態(tài)函數(shù)和類函數(shù)
python中支持兩種基于類名訪問成員函數(shù):靜態(tài)函數(shù)和類函數(shù)
不同點(diǎn):類函數(shù)有一個(gè)隱形參數(shù)cls可以用來獲取類信息
靜態(tài)函數(shù)使用裝飾器@staicmethod定義
類函數(shù)使用裝飾器@classmethod定義
4、以下劃線開頭的函數(shù)
- 單前導(dǎo)下劃線:_var
- 單末尾下劃線:var_
- 雙前導(dǎo)下劃線:__var
- 雙前導(dǎo)和末尾下劃線:
__var__
- 單下劃線:_
單線劃:_var
下劃線前綴的含義是告知其他程序員:以單個(gè)下劃線開頭的變量或方法僅供內(nèi)部使用。 該約定在PEP 8中有定義。這不是Python強(qiáng)制規(guī)定的。 Python不像Java那樣在“私有”和“公共”變量之間有很強(qiáng)的區(qū)別。
如果使用通配符從模塊中導(dǎo)入所有名稱,則Python不會(huì)導(dǎo)入帶有前導(dǎo)下劃線的名稱(除非模塊定義了覆蓋此行為的__all__
列表)
# This is my_module.py: def external_func(): return 23 def _internal_func(): return 42
>>> from my_module import * >>> external_func() 23 >>> _internal_func() NameError: "name '_internal_func' is not defined"
與通配符導(dǎo)入不同,常規(guī)導(dǎo)入不受前導(dǎo)單個(gè)下劃線命名約定的影響:
>>> import my_module >>> my_module.external_func() 23 >>> my_module._internal_func() 42
單末尾下劃線 var_
有時(shí)候,一個(gè)變量的最合適的名稱已經(jīng)被一個(gè)關(guān)鍵字所占用。 因此,像class或def這樣的名稱不能用作Python中的變量名稱。 在這種情況下,你可以附加一個(gè)下劃線來解決命名沖突,總之,單個(gè)末尾下劃線(后綴)是一個(gè)約定,用來避免與Python關(guān)鍵字產(chǎn)生命名沖突。 PEP 8解釋了這個(gè)約定。
雙前導(dǎo)下劃線:__var
到目前為止,我們所涉及的所有命名模式的含義,來自于已達(dá)成共識(shí)的約定。 而對(duì)于以雙下劃線開頭的Python類的屬性(包括變量和方法),情況就有點(diǎn)不同了。雙下劃線前綴會(huì)導(dǎo)致Python解釋器重寫屬性名稱,以避免子類中的命名沖突。這也叫做名稱修飾(name mangling) — 解釋器會(huì)更改變量的名稱,以便在類被擴(kuò)展的時(shí)候不容易產(chǎn)生沖突。對(duì)于該屬性的調(diào)用可以通過方法調(diào)用,而不能直接調(diào)用該屬性,類似實(shí)現(xiàn)屬性的私有,例如:
class ManglingTest: def __init__(self): self.__mangled = 'hello' def get_mangled(self): return self.__mangled >>> ManglingTest().get_mangled() # 通過方法獲取該函數(shù)的值 'hello' >>> ManglingTest().__mangled # 直接調(diào)用該屬性時(shí)會(huì)報(bào)錯(cuò) AttributeError: "'ManglingTest' object has no attribute '__mangled'"
但我們依然可以通過特殊方法來直接獲取該屬性的值,即通過(_類名__屬性)的方式獲取,例如
>>> ManglingTest()._ManglingTest__mangled 'hello'
所以在python中并沒有真正的私有變量,python解釋器會(huì)自動(dòng)將__var修飾為: _類名__屬性
,該特性對(duì)于以雙下劃線開頭的方法依然適用
class MangledMethod: def __method(self): return 42 def call_it(self): return self.__method() >>> MangledMethod().__method() # 直接調(diào)用該方法會(huì)報(bào)錯(cuò) AttributeError: "'MangledMethod' object has no attribute '__method'" >>> MangledMethod().call_it() 42 >>> MangledMethod()._MangledMethod__method() # 通過該形式也是可以調(diào)用該方法 42
雙前導(dǎo)和雙末尾下劃線 var
如果一個(gè)名字同時(shí)以雙下劃線開始和結(jié)束,則不會(huì)應(yīng)用名稱修飾。不同于僅有雙下滑線開頭的變量或函, 由雙下劃線前綴和后雙下滑線包圍的變量不會(huì)被Python解釋器修改,但是,Python保留了有雙前導(dǎo)和雙末尾下劃線的名稱,用于特殊用途。 這樣的例子有,__init__
(對(duì)象構(gòu)造函數(shù)),或__call__
(該函數(shù)是使得一個(gè)對(duì)象可以被調(diào)用)最好避免在自己的程序中使用以雙下劃線開頭和結(jié)尾的名稱,以避免與將來Python語言的變化產(chǎn)生沖突。
單下劃線
按照習(xí)慣,有時(shí)候單個(gè)獨(dú)立下劃線是用作一個(gè)名字,來表示某個(gè)變量是臨時(shí)的或無關(guān)緊要的。
例如,在下面的循環(huán)中,我們不需要訪問正在運(yùn)行的索引,我們可以使用“_”來表示它只是一個(gè)臨時(shí)值:
>>> for _ in range(32): ... print('Hello, World.') >>> car = ('red', 'auto', 12, 3812.4) >>> color, _, _, mileage = car >>> color 'red' >>> mileage 3812.4 >>> _ 12
到此這篇關(guān)于python中特殊文件和特殊函數(shù)的文章就介紹到這了,更多相關(guān)python特殊文件和特殊函數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
django 微信網(wǎng)頁授權(quán)登陸的實(shí)現(xiàn)
這篇文章主要介紹了django 微信網(wǎng)頁授權(quán)登陸的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07如何從Python字符串中刪除最后一個(gè)分號(hào)或者逗號(hào)
這篇文章主要介紹了從?Python?中的字符串中刪除最后一個(gè)分號(hào)或者逗號(hào)的兩種方法,本文通過示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-04-04Python?如何將?matplotlib?圖表集成進(jìn)到PDF?中
這篇文章主要介紹了Python?如何將?matplotlib?圖表集成進(jìn)到PDF?中,文章介紹內(nèi)容詳細(xì),具有一定的參考價(jià)值,需要的小伙伴可以參考一下,希望對(duì)你的學(xué)習(xí)有所幫助2022-03-03django xadmin中form_layout添加字段顯示方式
這篇文章主要介紹了django xadmin中form_layout添加字段顯示方式,具有很好的 參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-03-03使用Python實(shí)現(xiàn)tail的示例代碼
tail是一個(gè)常用的Linux命令, 它可以打印文件的后面n行數(shù)據(jù), 也能實(shí)時(shí)輸出文件的追加數(shù)據(jù)。本文就來用Python實(shí)現(xiàn)tail,感興趣的可以了解一下2023-03-03淺談pytorch中stack和cat的及to_tensor的坑
這篇文章主要介紹了pytorch中stack和cat的及to_tensor的坑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-05-05