總進口
最常用的導入方法大概是這樣的:
導入系統
只需使用import,然後指定要導入的模塊或包。以這種方式導入的優點是,您可以壹次導入多個包或模塊:
導入操作系統、系統、時間
雖然這樣可以節省空間,但是違反了Python風格指南。Python風格指南建議每個import語句位於單獨的壹行。
有時當導入壹個模塊時,您想要重命名該模塊。這個功能很容易實現:
將系統作為系統導入
打印(系統.平臺)
上面的代碼將導入的sys模塊重命名為system。我們可以像以前壹樣調用模塊的方法,但是我們可以使用壹個新的模塊名。還有壹些子模塊必須使用點符號導入。
導入urllib.error
這種情況並不常見,但了解壹些也無妨。
使用from語句導入
有時我們只想導入壹個模塊或庫的壹部分。那麽Python是如何做到這壹點的呢:
從functools導入lru_cache
上面壹行代碼允許妳直接調用lru_cache。如果以正常方式導入functools,必須像這樣調用lru_cache:
functools.lru_cache(*args)
根據實際使用場景,上述做法可能更好。在復雜的代碼庫中,查看函數的導入位置非常有用。但是,如果妳的代碼維護得很好,高度模塊化,那麽只從某個模塊導入壹部分內容是非常方便簡潔的。
當然,妳也可以使用from方法導入模塊的所有內容,就像這樣:
從操作系統導入*
這在某些情況下很方便,但也會破壞您的名稱空間。問題是您可能定義了壹個與導入模塊同名的變量或函數,如果您試圖使用。
os模塊中具有相同名稱的變量或函數實際上將使用您自己定義的內容。因此,您可能會以壹個相當混亂的邏輯錯誤而告終。
標準庫中我推薦完全導入的唯壹模塊是Tkinter。
如果妳碰巧編寫了自己的模塊或包,有人會建議妳在__init__中導入所有內容。py文件,使模塊或包使用起來更方便。我個人更喜歡顯式導入,而不是隱式導入。
您還可以折衷並從壹個包中導入多個項目:
從操作系統導入路徑,遍歷,取消鏈接從操作系統導入uname,刪除
在上面的代碼中,我們從os模塊中導入了五個函數。您可能已經註意到,我們通過多次從同壹個模塊導入它來實現它。當然,如果您願意,也可以使用括號壹次導入多個項目:
從操作系統導入(路徑、遍歷、取消鏈接、uname、
移除、重命名)
這是壹種有用的技術,但是您也可以用另壹種方式來改變它:
從os導入路徑,walk,unlink,uname,\
刪除,重命名
上面的反斜杠是Python中的延續字符,告訴解釋器這壹行代碼延續到下壹行。
相對進口
PEP 328介紹了引入相對導入的原因,以及選擇哪種語法。具體來說,用壹個句點來確定如何相對導入其他包或模塊。這樣做的原因是為了避免導入到標準庫中的模塊之間的意外沖突。這裏我們以PEP 328中給出的文件夾結構為例,看看相對導入是如何工作的:
我的_包/
__init__。巴拉圭
子包1/
__init__。巴拉圭
模塊_x.py
模塊_y.py
子包2/
__init__。巴拉圭
模塊_z.py
模塊_a.py
在本地磁盤上找到壹個地方來創建上述文件和文件夾。在頂級__init__中。py文件中,輸入以下代碼:
從。從導入子包1。導入子包2
接下來,進入子包1文件夾,編輯__init__。py文件,並輸入以下代碼:
從。從導入模塊_ xfrom。導入模塊_y
現在編輯module_x.py文件,並輸入以下代碼:
從。模塊_y將垃圾郵件作為垃圾郵件導入
def main():
火腿()
最後,編輯module_y.py文件並輸入以下代碼:
def spam():
打印('垃圾郵件' * 3)
打開終端,cd到my_package包所在的文件夾,但不要輸入my_package。運行該文件夾中的Python解釋器。我使用IPython是因為它的自動補全功能非常方便:
在[1]:導入我的_包
in[2]:my _ package . subpackage 1 . module _ xOut[2]:& lt;組件
my _ package . subpackage 1 . module _ x ' from
my _ package/sub package 1/module _ x . py ' & gt;
in[3]:my _ package . subpackage 1 . module _ x . main()spam spam
相對導入適用於您最終將放入包中的代碼。如果妳寫了很多相關性很強的代碼,就應該使用這種導入方法。
妳會發現PyPI上很多流行的包也是用的相對導入。另請註意,如果要跨多個文件級別導入,只需使用多個句點。然而,佩普
建議相對進口水平不要超過兩級。
還要註意,如果將if _ _ name _ =' _ _ main _ _ '添加到module_x.py文件中,然後嘗試運行該文件,將會遇到壹個無法理解的錯誤。編輯文件,試壹試!
從。模塊_y將垃圾郵件作為垃圾郵件導入
def main():
火腿()
if __name__ == '__main__ ':
#這樣不行!
主()
現在從終端進入subpackage1文件夾,並執行以下命令:
python模塊_x.py
如果您使用的是Python 2,您應該會看到以下錯誤消息:
回溯(最近壹次呼叫):
文件“module_x.py”,第1行,在
從。module_y將垃圾郵件作為hamvalue導入錯誤:試圖在非包中進行相對導入
如果您使用的是Python 3,錯誤消息如下所示:
回溯(最近壹次呼叫):
文件“module_x.py”,第1行,在
從。module_y將垃圾郵件作為hamSystemError導入:父模塊“”未加載,無法執行相對導入
這意味著module_x.py是壹個包中的模塊,妳嘗試在腳本模式下執行它,但是這個模式不支持相對導入。
如果您想在自己的代碼中使用這個模塊,您必須將它添加到Python的導入搜索路徑中。最簡單的方法如下:
import sys sys . path . append('/path/to/folder/containing/my _ package ')import my _ package
請註意,您需要在my_package之上添加文件夾路徑,而不是my_package本身。原因是my_package是我們要使用的包,所以如果添加了它的路徑,就無法使用這個包。
接下來說說可選導入。
可選進口(可選進口)
如果您想首先使用壹個模塊或包,但是還想有沒有這個模塊或包的替代方案,您可以使用可選的導入方法。這樣做可以導入和支持壹個軟件的多個版本,或者實現性能提升。以github2包中的代碼為例:
嘗試:
#對於Python 3
從http.client導入響應除了導入錯誤:#對於Python 2.5-2.7
嘗試:
來自httplib導入響應# NOQA
Python 2.4的ImportError: #除外
從BaseHTTPServer導入BaseHTTPRequestHandler as _BHRH
responses = dict([(k,v[0]) for k,v in _BHRH.responses.items()])
Lxml包也有可選的導入方法:
嘗試:
從urlparse導入urljoin
從urllib2導入urlopenexcept導入錯誤:
# Python 3
從urllib.parse導入urljoin
從urllib.request導入urlopen
如上例所示,可選導入的使用非常普遍,是壹項值得掌握的技能。
本地進口
當您在本地範圍內導入模塊時,您正在執行本地導入。如果您在Python腳本文件的頂部導入壹個模塊,您就將該模塊導入到了全局範圍內,這意味著以後的任何函數或方法都可以訪問該模塊。例如:
導入sys #全局範圍
定義平方根(a):
#此導入是對平方根函數的局部作用域
導入數學
返回math.sqrt(a)
def my_pow(base_num,power):
返回math.pow(base_num,power)
if __name__ == '__main__ ':
print(平方根(49))
print(my_pow(2,3))
這裏,我們將sys模塊導入到全局範圍中,但是我們不使用這個模塊。然後,在平方根函數中,我們將計算。
該模塊被導入到函數的局部範圍內,這意味著math模塊只能在square_root函數內使用。如果我們試圖在my_pow函數中使用它
數學,將引發NameError。嘗試執行這個腳本,看看會發生什麽。
使用局部作用域的壹個優點是,您使用的模塊可能需要很長時間才能導入。如果是這樣的話,把它放在壹個不常調用的函數裏,可能比直接全局做更合理。
從域導入。說實話,我幾乎從不使用部分導入,主要是因為如果模塊中到處都是導入語句,那麽這樣做的原因和目的就很難講了。
按照慣例,所有導入語句都應該位於模塊的頂部。
進口註意事項
程序員在導入模塊時經常會犯幾個錯誤。這裏我們介紹兩個。
循環進口(循環進口)
涵蓋進口(暫譯為涵蓋進口)
我們先來看看循環導入。
循環導入
如果妳創建了兩個模塊,並把它們相互導入,那麽就會出現循環導入。例如:
# a.pyimport b
def _ test():
打印(“在測試中”)
b.b _測試()
測試()
然後在同壹個文件夾中創建另壹個模塊,並將其命名為b.py
導入a
定義b_test():
打印(' In test_b " ')
測試()
b _測試()
如果運行任何模塊,都會引發AttributeError。這是因為兩個模塊都試圖相互導入。簡單來說,模塊A想導入模塊b。
,但是因為模塊B也在嘗試導入模塊A(此時正在執行),模塊A將無法完成模塊B。
的進口。我見過壹些解決這個問題的黑客,但壹般來說,妳應該做的是重構代碼來避免這種情況。
覆蓋導入
當您創建壹個與標準庫中的模塊同名的模塊時,如果您導入該模塊,將會有壹個覆蓋導入。例如,創建壹個名為math.py的文件,並在其中編寫以下代碼:
導入數學
定義平方根(數字):
返回math.sqrt(數字)
平方根(72)
現在打開終端並嘗試運行該文件,您將獲得以下回溯:
回溯(最近壹次呼叫):
文件“math.py”,第1行,在
導入數學
文件“/Users/michael/Desktop/math.py”,中的第6行
平方根(72)
文件“/Users/michael/Desktop/math.py”,第4行,平方根
返回math.sqrt(number)屬性錯誤:模塊“math”沒有屬性“sqrt”
這到底是怎麽回事?實際上,當您運行這個文件時,Python解釋器首先查找腳本當前運行的名為math的文件夾。
的模塊。在這個例子中,解釋器找到了我們正在執行的模塊,並試圖導入它。但是我們的模塊中沒有名為sqrt的函數或屬性,所以我們拋出它。
AttributeError .