溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Python中import是如何工作的

發(fā)布時(shí)間:2023-05-17 11:35:17 來源:億速云 閱讀:96 作者:zzz 欄目:編程語言

這篇“Python中import是如何工作的”文章的知識(shí)點(diǎn)大部分人都不太理解,所以小編給大家總結(jié)了以下內(nèi)容,內(nèi)容詳細(xì),步驟清晰,具有一定的借鑒價(jià)值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“Python中import是如何工作的”文章吧。

1.什么是模塊(module),什么是包(package)

模塊(module)

模塊與包的關(guān)系,可以類比文件和目錄,模塊就是文件。

Python 文檔中這樣描述,一個(gè) Python 文件就是一個(gè)模塊,Python 的文件名(不帶后綴.py)就是模塊名。

一個(gè) module 可以包含變量、函數(shù)和類,它們是該 module 定義的命名空間的一部分,因此變量的命名問題不是問題,因?yàn)閮蓚€(gè)不同的模塊可以有同名的變量、函數(shù)和類。

包(package)

模塊與包的關(guān)系,可以類比文件和目錄,包就是目錄。

package 里面可以有 module,也可以有子包(sub-package)。一個(gè)模塊定義一個(gè)命名空間,以便變量、函數(shù)和類可以在兩個(gè)不同的模塊中具有相同的名稱,同樣的,一個(gè)包對其組成的包和模塊做同樣的事情,可以通過點(diǎn)號(hào)訪問主包中的模塊和包。

一個(gè)基本的 package 可以包含 sub-package、modules、__init__.py(Python 3.3 之后非必需)、setup.py。一個(gè)可能的 package 結(jié)構(gòu)如下所示:

Python中import是如何工作的

而 setup.py 存在于你的 package 所在的主目錄中,包含配置信息,如所需的依賴項(xiàng)、腳本和子包。你還可以指定有關(guān) package 的元數(shù)據(jù),例如 package 的名稱、作者、描述等。

setup.py 是 pip 用來安裝你的包的文件。

2.import 時(shí)發(fā)生了什么

先舉一個(gè)簡單的例子,比如說同一個(gè)目錄有兩個(gè)文件,file1.py 和 file2.py,內(nèi)容很簡單,就打印各自的文件名,不同的是 file2.py 里面 import 了 file1:

#file1.py
print("This is file1.py")
#file2.py
print("This is file2.py")
import file1

運(yùn)行 file2.py 可以得到下面的結(jié)果:

? python file2.py
This is file2.py
This is file1.py

可以看出:

  • import 很直觀,用誰就 import 誰。

  • import 語句就是一個(gè)普通的語句,可以放在任何位置。

  • 一個(gè)文件被 import 的時(shí)候,就會(huì)被執(zhí)行,其內(nèi)部的類或?qū)ο髮⑻砑拥狡涿臻g。

我們還要知道 import 的搜索順序,只需要記住一點(diǎn),那就是 import 會(huì)去 sys.path 里面搜索。

比如我在 file2.py 的末尾添加一行代碼:import sys; print(sys.path) 就可以打印 import 的搜索路徑:

Python中import是如何工作的

可以看出 sys.path 的順序:

  • 會(huì)先搜索執(zhí)行腳本所在的路徑

  • 標(biāo)準(zhǔn)庫

  • 第三方庫 site-packages

關(guān)于 sys.path 需要你注意的是:

  • 在解釋器環(huán)境下,sys.path[0] 就是解釋器啟動(dòng)時(shí)所在的路徑 ''

  • sys.path 并不會(huì)依賴當(dāng)前程序的工作路徑 - os.getcwd(),僅僅依賴第一個(gè)腳本所在的路徑:

Python中import是如何工作的

  • 如果一個(gè)模塊導(dǎo)入另一個(gè)模塊,而后者又導(dǎo)入另一個(gè)模塊,則第一個(gè)模塊的 sys.path 是解釋器搜索第二個(gè)導(dǎo)入語句的位置。

一旦模塊或包被找到,就會(huì)執(zhí)行該模塊或包。如果包里面有初始化文件 __init__.py,導(dǎo)入的時(shí)候,會(huì)先執(zhí)行 __init__.py。

然后要導(dǎo)入的項(xiàng)目就添加到了其命名空間內(nèi),我們可以通過 xx.yy 的方式來使用。

3.什么時(shí)候用相對導(dǎo)入,什么時(shí)候用絕對導(dǎo)入

先看看什么是絕對導(dǎo)入,所謂絕對導(dǎo)入就是這樣的形式:

import aa
import aa.bb
from aa import bb

這樣的方式很直觀, import 會(huì)去 sys.path 查找就行了,如果遇到了 ModuleNotFoundError,思考一下為什么 sys.path 沒有我們要導(dǎo)入的包,或者手動(dòng)把這個(gè)包的路徑插入到 sys.path 中去。

再看看什么是相對導(dǎo)入,所謂相對導(dǎo)入就是這樣的形式:

from . import aa
from .aa import bb
from .. import yy

也就是說相對路徑中有個(gè) . 號(hào),用來表明要導(dǎo)入的模塊或當(dāng)前的包的相對位置。

舉個(gè)例子,我們 pythonimportexample 目錄下新建一個(gè)目錄 subpackage1,在 subpackage1 內(nèi)新建兩個(gè)文件 file3.py、file4.py。

內(nèi)容如下:

file3.py :

print("This is file3.py")

file4.py:

from . import file3
print("This is file4.py")

只要我們直接運(yùn)行 file4.py,那是一定會(huì)報(bào)錯(cuò)的:Python中import是如何工作的

Python 提示我們:

ImportError: attempted relative import with no known parent package

也就是說相對導(dǎo)入不知道父包是誰,換句話說,這是一個(gè)子包,必須讓父包來調(diào)用它,直接運(yùn)行這個(gè)文件是不行的,即使你在 file4.py 的目錄 subpackage1 同級(jí)的目錄執(zhí)行該文件也是不行的,見上圖。

但是在 file4.py 的目錄 subpackage1 同級(jí)的目錄作為一個(gè) module 來執(zhí)行是可以的,如下圖:

Python中import是如何工作的

換句話說,我們把 subpackage1 作為一個(gè)包來讓別人用,相對導(dǎo)入是可以的,比如說我們在目錄 subpackage1 同級(jí)的目錄新建一個(gè) file5.py 的文件,內(nèi)容如下:

file5.py:

from subpackage1 import file4。

然后,執(zhí)行 python file5.py 可以看出,相對導(dǎo)入已經(jīng)正常工作:

Python中import是如何工作的

結(jié)論

  • 如果是當(dāng)做腳本文件直接運(yùn)行的,使用絕對導(dǎo)入。

  • 如果是當(dāng)做模塊供其他文件導(dǎo)入,使用相對導(dǎo)入。

4.一個(gè)自定義包的例子

先上一個(gè)圖來看下目錄及引用結(jié)構(gòu),方塊的是目錄,橢圓的是文件,曲線是引用:

Python中import是如何工作的

其中 import_example 目錄下有 setup.py 和 run.py

run.py 導(dǎo)入了 file4、file5、file6。

file4 導(dǎo)入了 file3,file5 導(dǎo)入了 file3。

file6 導(dǎo)入了 file2,file2 導(dǎo)入了 file1。

現(xiàn)在我們來執(zhí)行一下 run.py 看下效果:

Python中import是如何工作的

可以看出所有相對導(dǎo)入都已正常工作,雖然 file3 被導(dǎo)入了兩次,但只執(zhí)行了一次,說明 Python 內(nèi)部已經(jīng)考慮了同一個(gè)包的多重導(dǎo)入問題。自定義包就是讓其他文件導(dǎo)入使用的,因此 pythonimportexample目錄下都使用相對導(dǎo)入。

以上就是關(guān)于“Python中import是如何工作的”這篇文章的內(nèi)容,相信大家都有了一定的了解,希望小編分享的內(nèi)容對大家有幫助,若想了解更多相關(guān)的知識(shí)內(nèi)容,請關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI