一、import 的基礎(chǔ)概念
什么是 import
在 Python 中,import語(yǔ)句用來(lái)導(dǎo)入其他 Python 文件,這些被導(dǎo)入的文件通常被稱為模塊(module)哀墓。其主要目的是實(shí)現(xiàn)代碼復(fù)用,即可以使用該模塊里定義的類喷兼、方法或者變量篮绰。例如在數(shù)學(xué)計(jì)算中,我們經(jīng)常會(huì)用到import math季惯,這里的math就是一個(gè)模塊吠各,通過(guò)這個(gè)導(dǎo)入語(yǔ)句,我們就可以在代碼中使用math模塊中定義的各種數(shù)學(xué)函數(shù)和常量勉抓,如math.pi等贾漏。
Python 如何尋找模塊
Python 會(huì)在兩個(gè)地方尋找模塊,一是sys.path琳状,這里包含了一般安裝的 Python 庫(kù)的目錄磕瓷;二是運(yùn)行文件所在的目錄盒齿。
sys.path是一個(gè)很重要的概念念逞,它是一個(gè)列表,存儲(chǔ)了 Python 解釋器在尋找模塊時(shí)的搜索路徑边翁。當(dāng)我們使用import語(yǔ)句導(dǎo)入一個(gè)模塊時(shí)翎承,Python 解釋器會(huì)按照sys.path中的路徑順序依次查找該模塊。如果在其中一個(gè)路徑中找到了該模塊符匾,就會(huì)停止搜索并導(dǎo)入這個(gè)模塊叨咖。
而運(yùn)行文件所在的目錄也是 Python 尋找模塊的一個(gè)重要位置。這意味著如果我們有一個(gè)模塊與運(yùn)行的腳本文件在同一目錄下啊胶,Python 也能夠找到并導(dǎo)入這個(gè)模塊甸各。例如,如果我們有一個(gè)名為main.py的腳本文件和一個(gè)名為my_module.py的模塊文件在同一目錄下焰坪,我們可以在main.py中使用import my_module來(lái)導(dǎo)入my_module.py模塊趣倾。
二、import 的用法分類
絕對(duì)導(dǎo)入
用法:import module_name 或 from package_name import module_name某饰。絕對(duì)導(dǎo)入涉及完整路徑列赎,即從項(xiàng)目的根文件夾復(fù)制到所需的模塊。
import module_name 的方式是直接導(dǎo)入一個(gè)模塊鲫骗,例如import math健爬,這里的math就是一個(gè)模塊,通過(guò)這個(gè)導(dǎo)入語(yǔ)句矛洞,我們就可以在代碼中使用math模塊中定義的各種數(shù)學(xué)函數(shù)和常量,如math.pi等。
from package_name import module_name 的方式是從一個(gè)包中導(dǎo)入特定的模塊剂跟,例如from pandas import Series,這樣就可以直接使用Series類來(lái)實(shí)例化對(duì)象酣藻。
用于導(dǎo)入 sys.path 中的包和運(yùn)行文件所在目錄下的包浩聋。絕對(duì)導(dǎo)入對(duì)于 sys.path 中的包和運(yùn)行文件所在目錄下的包是非常有效的。Python 會(huì)在兩個(gè)地方尋找模塊臊恋,一是sys.path衣洁,這里包含了一般安裝的 Python 庫(kù)的目錄;二是運(yùn)行文件所在的目錄抖仅。sys.path是一個(gè)列表坊夫,存儲(chǔ)了 Python 解釋器在尋找模塊時(shí)的搜索路徑。當(dāng)我們使用絕對(duì)導(dǎo)入語(yǔ)句導(dǎo)入一個(gè)模塊時(shí)撤卢,Python 解釋器會(huì)按照sys.path中的路徑順序依次查找該模塊环凿。如果在其中一個(gè)路徑中找到了該模塊,就會(huì)停止搜索并導(dǎo)入這個(gè)模塊放吩。而運(yùn)行文件所在的目錄也是 Python 尋找模塊的一個(gè)重要位置智听。這意味著如果我們有一個(gè)模塊與運(yùn)行的腳本文件在同一目錄下,Python 也能夠找到并導(dǎo)入這個(gè)模塊渡紫。
相對(duì)導(dǎo)入
寫(xiě)法:from. import module_name 等到推。相對(duì)導(dǎo)入指定從其當(dāng)前位置導(dǎo)入的對(duì)象或模塊,該位置是 import 語(yǔ)句駐留的位置惕澎。
from. import module_name 的寫(xiě)法是導(dǎo)入和自己同目錄下的模塊莉测。例如,在非運(yùn)行入口文件中唧喉,如果要導(dǎo)入和自己同目錄下的模塊捣卤,可以使用這種寫(xiě)法。
from.package_name import module_name 的寫(xiě)法是導(dǎo)入和自己同目錄的包的模塊八孝。
from.. import module_name 的寫(xiě)法是導(dǎo)入上級(jí)目錄的模塊董朝。
from..package_name import module_name 的寫(xiě)法是導(dǎo)入位于上級(jí)目錄下的包的模塊。每多一個(gè)點(diǎn)就多往上一層目錄干跛。
非運(yùn)行入口文件導(dǎo)入自己寫(xiě)的文件時(shí)需要相對(duì)導(dǎo)入子姜。對(duì)于非運(yùn)行入口文件,相對(duì)導(dǎo)入是一種簡(jiǎn)潔的方式來(lái)導(dǎo)入自己寫(xiě)的文件驯鳖。相對(duì)導(dǎo)入不會(huì)從sys.path中查找闲询,而是直接從當(dāng)前路徑下查找久免。在 Python3 中,默認(rèn)是絕對(duì)導(dǎo)入扭弧,相對(duì)導(dǎo)入需要特定的寫(xiě)法阎姥。例如,對(duì)于非運(yùn)行入口文件m3.py鸽捻,其導(dǎo)入m4.py需要使用相對(duì)導(dǎo)入:from. import m4呼巴。這樣可以確保正確地導(dǎo)入所需的模塊,避免出現(xiàn)導(dǎo)入錯(cuò)誤御蒲。
三衣赶、import 的注意事項(xiàng)
避免錯(cuò)誤導(dǎo)入同目錄文件
最好不要用絕對(duì)導(dǎo)入的第一種寫(xiě)法來(lái)導(dǎo)入同目錄下的文件,可能會(huì)出錯(cuò)厚满。
在 Python 中府瞄,雖然可以使用絕對(duì)導(dǎo)入來(lái)導(dǎo)入同目錄下的文件,但是這種做法并不推薦碘箍。例如遵馆,如果有兩個(gè)文件file_a.py和file_b.py在同一目錄下,直接使用import file_b這種絕對(duì)導(dǎo)入的第一種寫(xiě)法可能會(huì)導(dǎo)致錯(cuò)誤丰榴。具體原因可能是 Python 解釋器在查找模塊時(shí)货邓,可能會(huì)出現(xiàn)路徑?jīng)_突或者循環(huán)導(dǎo)入等問(wèn)題。參考資料中有多個(gè)例子提到了在同一目錄下導(dǎo)入文件可能出現(xiàn)的問(wèn)題四濒,如 “python 同一目錄下導(dǎo)入不了其他文件 - 51CTO 博客” 中提到了循環(huán)導(dǎo)入换况、環(huán)境問(wèn)題和命名沖突等可能導(dǎo)致同一目錄下導(dǎo)入失敗的原因。同時(shí)盗蟆,“pycharm 導(dǎo)入相同目錄文件報(bào)錯(cuò)解決辦法 - CSDN 博客” 也給出了在遠(yuǎn)程桌面環(huán)境下使用 pycharm 導(dǎo)入同目錄文件報(bào)錯(cuò)的情況及解決方法的探索戈二。
運(yùn)行入口文件的相對(duì)導(dǎo)入限制
運(yùn)行入口文件可以使用相對(duì)導(dǎo)入,但不能用python 文件名.py命令姆涩,而是需要進(jìn)入相應(yīng)目錄挽拂,使用python -m 路徑.文件名來(lái)運(yùn)行惭每。
當(dāng)使用相對(duì)導(dǎo)入時(shí)骨饿,運(yùn)行入口文件有一定的限制。不能直接使用python 文件名.py的方式運(yùn)行入口文件台腥,因?yàn)檫@種方式下 Python 解釋器無(wú)法正確識(shí)別相對(duì)導(dǎo)入的路徑宏赘。相對(duì)導(dǎo)入是指定從其當(dāng)前位置導(dǎo)入的對(duì)象或模塊,該位置是 import 語(yǔ)句駐留的位置黎侈。例如察署,在非運(yùn)行入口文件中,如果要導(dǎo)入和自己同目錄下的模塊峻汉,可以使用from. import module_name的寫(xiě)法贴汪。但是對(duì)于運(yùn)行入口文件脐往,需要進(jìn)入相應(yīng)目錄,使用python -m 路徑.文件名的方式來(lái)運(yùn)行扳埂,這樣 Python 解釋器才能正確處理相對(duì)導(dǎo)入业簿。參考資料中 “python 模塊導(dǎo)入注意事項(xiàng) - CSDN 博客” 提到了入口文件不能使用相對(duì)導(dǎo)入的錯(cuò)誤示例及原因分析,“python 使用相對(duì)導(dǎo)入_mob649e8168f1bb 的技術(shù)博客 - 51CTO 博客” 也詳細(xì)介紹了相對(duì)導(dǎo)入的步驟及運(yùn)行入口文件的正確方式阳懂。
四梅尤、import 的常見(jiàn)場(chǎng)景
導(dǎo)入文件模塊
import 文件名,導(dǎo)入整個(gè)文件模塊岩调。這種方式會(huì)將整個(gè)文件中的代碼復(fù)制到當(dāng)前文件中巷燥,效率相對(duì)較低。例如号枕,如果有一個(gè)名為my_module.py的文件缰揪,其中包含一些函數(shù)和變量,我們可以使用import my_module來(lái)導(dǎo)入這個(gè)模塊葱淳。然后邀跃,要使用模塊中的函數(shù)或變量時(shí),需要通過(guò)模塊名來(lái)訪問(wèn)蛙紫,如my_module.my_function()拍屑。
效率較低的原因在于,無(wú)論當(dāng)前文件是否需要模塊中的所有內(nèi)容坑傅,都會(huì)將整個(gè)模塊的代碼復(fù)制過(guò)來(lái)僵驰。在一些大型項(xiàng)目中,如果過(guò)多地使用這種方式導(dǎo)入模塊唁毒,可能會(huì)導(dǎo)致加載時(shí)間變長(zhǎng)蒜茴,占用更多的內(nèi)存資源。
導(dǎo)入文件中的指定函數(shù)
from 文件名 import 函數(shù)名浆西,這種方式可以提高代碼運(yùn)行效率粉私。它只導(dǎo)入文件中特定的函數(shù),避免了導(dǎo)入整個(gè)模塊帶來(lái)的不必要的開(kāi)銷近零。例如诺核,從my_module.py中只導(dǎo)入一個(gè)名為my_function的函數(shù),可以使用from my_module import my_function久信。這樣窖杀,在當(dāng)前文件中就可以直接使用my_function()來(lái)調(diào)用這個(gè)函數(shù),無(wú)需再通過(guò)模塊名來(lái)訪問(wèn)裙士。
導(dǎo)入文件中的所有函數(shù)
from 文件名 import *入客,這種方式不推薦使用,因?yàn)樗赡軙?huì)導(dǎo)致命名沖突和可讀性問(wèn)題。當(dāng)使用這種方式導(dǎo)入多個(gè)模塊時(shí)桌硫,如果不同模塊中存在相同名稱的函數(shù)或變量夭咬,就會(huì)產(chǎn)生沖突,難以確定到底使用的是哪個(gè)模塊中的內(nèi)容铆隘。而且皱埠,這種方式使得代碼的可讀性降低,其他人在閱讀代碼時(shí)難以確定函數(shù)的來(lái)源咖驮。
給導(dǎo)入的函數(shù)設(shè)置別名
from 文件名 import 函數(shù)名 as 新的函數(shù)名或import 文件名 as 新模塊名边器,這種方式可以簡(jiǎn)化代碼。例如托修,from my_module import my_function as mf忘巧,這樣在當(dāng)前文件中就可以使用mf()來(lái)代替my_module.my_function()∧廊校或者import my_module as mm砚嘴,然后使用mm.my_function()來(lái)調(diào)用模塊中的函數(shù)。設(shè)置別名可以使代碼更加簡(jiǎn)潔易讀涩拙,特別是當(dāng)模塊名或函數(shù)名比較長(zhǎng)時(shí)际长,使用別名可以提高代碼的編寫(xiě)效率。