詳解Python中import模塊導(dǎo)入的實(shí)現(xiàn)原理
什么是模塊
一個(gè).py文件就是一個(gè)模塊,即Module。模塊分為三種:python標(biāo)準(zhǔn)庫(kù)、第三方模塊、應(yīng)用程序自定義模塊。
- import語(yǔ)句 – 導(dǎo)入模塊
- Directory – 文件夾(空的)
- Package – 比文件夾多了一個(gè)__init__.py
""" file: cal.py """ def add(x, y) return x+y def sub(x, y) return x-y print(‘hello cal') """ file: test.py """ import cal print(cal.add(1, 2))
import做了什么?
import導(dǎo)入模塊的時(shí)候,首先會(huì)把導(dǎo)入的文件執(zhí)行一遍,比如說(shuō)我們運(yùn)行test.py的時(shí)候,print(‘hello cal’)也會(huì)被執(zhí)行,因?yàn)閕mport cal的時(shí)候就把cal.py運(yùn)行了一遍。所以,我們?cè)谀K文件中只寫(xiě)功能(也就是函數(shù)),而不要寫(xiě)可執(zhí)行的語(yǔ)句。
- 執(zhí)行被引入的py文件,即使只引入一個(gè)變量(from cal import add),也會(huì)運(yùn)行整個(gè)文件。
- 引入變量名 → 文件名變量
引入多個(gè)模塊
import cal, time
只引入一個(gè)方法
# 只引入一個(gè)方法 from cal import add print(add(1, 2)) #可以直接使用add,不用加cal.
引入所有方法,不推薦使用,你并不知道都引入了哪些變量,可能會(huì)出現(xiàn)本文件變量與引入變量名字重復(fù)的情況。
#引入所有方法 – 不推薦使用,你并不知道都引入了哪些變量,可能會(huì)出現(xiàn)本文件變量與引入變量名字重復(fù)的情況。 from cal import * #新的變量名會(huì)覆蓋舊的變量名
#+++++++++++++++++++++++++++ from cal import * def add(x, y) return x+y+100 print(add(1, 2)) #+++++++++++++++++++++++++++ def add(x, y) return x+y+100 from cal import * print(add(1, 2)) #+++++++++++++++++++++++++++
import搜索路徑
import sys print(sys.path) #查看路徑
path中包含python自己定義的路徑,以及當(dāng)前執(zhí)行的py文件的路徑,也就是說(shuō)當(dāng)前執(zhí)行路徑會(huì)被自動(dòng)加入到sys.path中,import就是按照這些路徑去搜索被引入的變量的。也可以通過(guò)手動(dòng)添加路徑
from path import cal #path就是cal所在的路徑
import導(dǎo)入模塊的原理
首先import會(huì)根據(jù)路徑找到文件,根據(jù)路徑找到模塊后把模塊加載到內(nèi)存中執(zhí)行一遍,執(zhí)行的時(shí)候是把模塊的內(nèi)容拷貝到當(dāng)前文件執(zhí)行。import導(dǎo)入是將模塊從磁盤(pán)中把磁盤(pán)文件導(dǎo)入到內(nèi)存中,這個(gè)速度是比較慢的,實(shí)際上,在導(dǎo)入時(shí)會(huì)有一個(gè)導(dǎo)入緩存,同一個(gè)模塊在導(dǎo)入第一次的時(shí)候會(huì)有一個(gè)緩存,以后再導(dǎo)入都是用的緩存的導(dǎo)入,所以有時(shí)候你可能遇到這樣的問(wèn)題,被導(dǎo)入的文件已經(jīng)刪除了,但是程序還是能運(yùn)行,這是因?yàn)槌绦蚴褂玫氖蔷彺娴膶?dǎo)入模塊。
from path import mode,它相當(dāng)于把路徑進(jìn)行了一次拼接path\mode.py,這是from的工作。路徑拼接是在當(dāng)前執(zhí)行文件的路徑基礎(chǔ)上進(jìn)行拼接。
當(dāng)引入了很多模塊的時(shí)候,一個(gè)目錄下會(huì)有很多py文件,一般把bin.py作為要執(zhí)行的文件,也就是整個(gè)程序的入口。而邏輯主文件叫做main.py,這里面包含了程序的主要邏輯,其他功能都放到其它文件中作為一個(gè)模塊。我們?cè)谶\(yùn)行的時(shí)候,運(yùn)行bin.py,由bin.py去調(diào)用main.py中的主邏輯。也就是說(shuō)只有bin是可執(zhí)行的,其余文件都不應(yīng)作為執(zhí)行文件。
前面說(shuō)過(guò),sys.path中只會(huì)加入當(dāng)前運(yùn)行程序所在的路徑,bin.py是整個(gè)程序的運(yùn)行文件,也就是說(shuō)sys.path中只會(huì)加入bin.py的路徑,假如說(shuō)文件有如下導(dǎo)入關(guān)系
假如說(shuō)main.py和cal.py在同一級(jí)目錄,那么不用加路徑即可導(dǎo)入,但是如果bin.py和這兩個(gè)文件不在同一級(jí)目錄(比如在上一級(jí)目錄),那么bin.py導(dǎo)入main.py的時(shí)候就要加上main.py的路徑,但是這樣在執(zhí)行的時(shí)候會(huì)報(bào)錯(cuò),因?yàn)閎in.py間接導(dǎo)入了cal.py,并且bin.py只加了main.py的路徑而沒(méi)有加cal.py的路徑,前面說(shuō)過(guò)sys.py只會(huì)包含當(dāng)前運(yùn)行路徑,也就是bin.py的路徑。解決方法有兩個(gè):
- 在main.py中加上cal.py的路徑from path import cal;
- 把路徑加到sys.path中;
file 獲取當(dāng)前文件名
os.path.dirname(__file__) #獲取當(dāng)前文件路徑 os.path.dirname(os.path.dirname(__file__)) #獲取當(dāng)前文件的上一級(jí)路徑
pycharm會(huì)自己根據(jù)當(dāng)前文件名獲取絕對(duì)路徑,并把絕對(duì)路徑通過(guò)os.path.dirname()返回給我們os.path.dirname(file),但是在終端運(yùn)行的時(shí)候,終端并沒(méi)有這個(gè)功能,我們需要自己去找到絕對(duì)路徑,然后根據(jù)絕對(duì)路徑找到文件名,并反推出上一級(jí)目錄。
p = os.path.dirname(__file__) #獲取當(dāng)前文件的絕對(duì)路徑 BASEDIR = os.path.dirname(os.path.dirname(p)) sys.psth.append(BASEDIR)
實(shí)際上,這三步的操作相當(dāng)于把當(dāng)前運(yùn)行文件的上一級(jí)目錄通過(guò)相對(duì)路徑的方式添加到了環(huán)境變量。如果我們以絕對(duì)路徑的方式添加環(huán)境變量,當(dāng)我們換了電腦或者環(huán)境,環(huán)境變量就失效了。我們這樣通過(guò)程序找出相對(duì)路徑來(lái)添加到環(huán)境變量,只要將當(dāng)前整個(gè)工程一塊拷貝到別的機(jī)器,就一定可以找到這個(gè)環(huán)境變量。
以上就是詳解Python中import模塊導(dǎo)入的實(shí)現(xiàn)原理的詳細(xì)內(nèi)容,更多關(guān)于Python import模塊導(dǎo)入的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
利用Python實(shí)現(xiàn)翻譯HTML中的文本字符串
這篇文章主要為大家介紹了如何利用Python實(shí)現(xiàn)翻譯HTML中的文本字符串功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以動(dòng)手嘗試一下2022-06-06Python的Pillow庫(kù)進(jìn)行圖像文件處理(圖文詳解)
本文詳解的講解了使用Pillow庫(kù)進(jìn)行圖片的簡(jiǎn)單處理,使用PyCharm開(kāi)發(fā)Python的詳細(xì)過(guò)程和各種第三方庫(kù)的安裝與使用。感興趣的可以了解一下2021-11-11

Python實(shí)戰(zhàn)之畫(huà)哆啦A夢(mèng)(超詳細(xì)步驟)

Python中判斷subprocess調(diào)起的shell命令是否結(jié)束

Python 機(jī)器學(xué)習(xí)庫(kù) NumPy入門教程

Python OpenCV讀取視頻報(bào)錯(cuò)的問(wèn)題解決

keras中模型訓(xùn)練class_weight,sample_weight區(qū)別說(shuō)明