欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

python中的import絕對導(dǎo)入與相對導(dǎo)入詳解

 更新時間:2023年11月03日 10:03:27   作者:驚瑟  
這篇文章主要介紹了python中的import絕對導(dǎo)入與相對導(dǎo)入詳解,在使用python做一些簡單項(xiàng)目時,import一般不會出現(xiàn)問題,但項(xiàng)目結(jié)構(gòu)復(fù)雜時,import可能發(fā)生報(bào)錯,需要的朋友可以參考下

前言

在使用python做一些簡單項(xiàng)目時,import一般不會出現(xiàn)問題,但項(xiàng)目結(jié)構(gòu)復(fù)雜時,import可能發(fā)生報(bào)錯。

最常見的錯誤是:ImportError: attempted relative import with no known parent package,要弄清楚問題本質(zhì),就需要了解import的工作機(jī)制了。

眾所周知,import分為絕對導(dǎo)入和相對導(dǎo)入,兩者的唯一區(qū)別就是是否使用了"." 為一探究竟,構(gòu)建以下項(xiàng)目目錄:

imp_test
├── entrance1.py
├── pakg1
│   ├── __init__.py
│   ├── module1.py
│   ├── module2.py
│   └── pakg1_1
│       └── __init__.py
└── pakg2
    └── __init__.py

一、絕對導(dǎo)入

先明確下,python中modules的概念并不統(tǒng)一,官方文檔中的modules有時候指的是package,有時候指的是py文件,為了避免歧義,本文中module特指py文件,modules指“py文件以及包”。 形式如import XXX或from XXX import a,b 都是絕對導(dǎo)入。比如在module1.py中導(dǎo)入module2.py中的內(nèi)容:from module2 import v2。 當(dāng)執(zhí)行絕對導(dǎo)入時,解釋器做了以下這些事情:

查找built-in modules(內(nèi)置模塊)。內(nèi)置模塊是python解釋器的一部分,用C語言編寫,常見的有os time sys json;

查找sys.path包含的目錄,包括:

  • 啟動文件所在的目錄
  • 當(dāng)前項(xiàng)目的頂級目錄(注意:前提是使用IDE,在命令行直接import沒有這個目錄,可以理解為,在新建項(xiàng)目時IDE自動將項(xiàng)目目錄添加到了sys.path中了)
  • 當(dāng)前解釋器lib目錄,主要是第三方包的安裝目錄

因此可以得出結(jié)論:絕對導(dǎo)入時,啟動文件所在的目錄下以及項(xiàng)目頂級目錄下的包或py文件可以直接導(dǎo)入(此時IDE可以自動補(bǔ)全)。值得注意的是,當(dāng)項(xiàng)目中涉及多個層級目錄下的py文件或模塊的互相導(dǎo)入,所有py文件的sys.path都是一樣的,絕對導(dǎo)入的搜索目錄針對的都是啟動文件。 可以測試,當(dāng)啟動文件為pakg1.module1.py,在pakg1.module1.py中執(zhí)行絕對導(dǎo)入,都沒問題:

#pakg1.module1.py
import pakg1_1 # 當(dāng)前目錄下的包
import pakg2 # 頂層目錄下的包
import module2 # py文件

但是當(dāng)啟動文件為entrance1.py時,在entrance1.py執(zhí)行絕對導(dǎo)入:

#entrance1.py
import pakg1.module1

就會提示在pakg1.module1.py中import module2報(bào)錯:

ModuleNotFoundError: No module named 'module2'

原因如上所述,啟動文件為entrance1.py時,module2并未在其搜索目錄中。

二、相對導(dǎo)入

帶".“的導(dǎo)入是相對導(dǎo)入,如:from .XXX import a,b,要理解相對導(dǎo)入,關(guān)鍵在于搞明白”."是什么含義。 在pakg1.module1.py執(zhí)行相對導(dǎo)入:

#module1.py
print('pakg1.module1 __name__ is:',__name__)
from .module2 import v2
print(v2)

并啟動pakg1.module1.py,得到報(bào)錯:

ImportError: attempted relative import with no known parent package
pakg1.module1 __name__ is: __main__

要理解"."的含義,關(guān)鍵在于理解python的__name__屬性:事實(shí)上python所有對象都有該屬性,包括包和py文件。對于py文件,這個屬性不是一成不變的:

  • 當(dāng)其是啟動文件時,該文件的__name__ = "__main__";
  • 當(dāng)其不是啟動文件時,__name__ = pakg_name.module_name,其中pakg_name從頂層目錄的包開始算起,有多層則以此類推;

而相對導(dǎo)入中的".“則指的是,該文件的__name__屬性去掉最后的文件名前面的部分,即該文件的“父包”,當(dāng)該文件是啟動文件時,由于__name__ = "__main__",此時“父包”為空,故會報(bào)錯no known parent package。 事實(shí)上,python的modules還有一個屬性__package__,官方文檔解釋如下:

在這里插入圖片描述

從以上文字我們可以了解到:對于包來講,__package__ == __name__,而對于py文件來講,__package__則代表其父包,并且對于在項(xiàng)目頂層目錄的py文件(對于啟動文件,不管實(shí)際目錄怎樣,都認(rèn)為它是頂層文件),該屬性為空。因此我們可以認(rèn)為某文件中相對導(dǎo)入的”.",指的就是該文件的__package__屬性。

三、結(jié)論

弄明白原理后,在實(shí)際項(xiàng)目中涉及到import,可以總結(jié)以下幾條原則:

  • 如果項(xiàng)目層級不是特別深,而結(jié)構(gòu)預(yù)計(jì)不會做很大調(diào)整,最保險(xiǎn)的導(dǎo)入方式是:統(tǒng)統(tǒng)使用絕對導(dǎo)入,并且從項(xiàng)目頂層包開始引入;
  • 反之,當(dāng)項(xiàng)目層級很深,而結(jié)構(gòu)可能面臨調(diào)整時,可以使用相對導(dǎo)入,但需要保證該文件不是啟動文件;
  • 對于項(xiàng)目頂層文件,無論其是不是啟動文件,都不要使用相對導(dǎo)入,因?yàn)轫攲游募偕蠈邮琼?xiàng)目目錄,沒有父包了,即__package__ = ''。

四、關(guān)于__init__

為什么每個包要有一個__init__?首先是因?yàn)樗梢詷?biāo)志這是一個包,可以被import;其次,在實(shí)際項(xiàng)目中,我們需要對外暴露的內(nèi)容更多的是函數(shù)、類或變量,如果要導(dǎo)入這些對象,就需要from pakg_name.module_name import a,b,c,可能略顯冗長,而如果提前在包的__init__中將要暴露的對象導(dǎo)入,這些對象將屬于“包的子集”,導(dǎo)入時只需要精確到包就行了,即from pakg_name import a,b,c,除此之外,使用__all__還可以約束該包要暴露的內(nèi)容,有“白名單”效果。因此在__init__明確每個包要暴露的對象是很好的習(xí)慣。

到此這篇關(guān)于python中的import絕對導(dǎo)入與相對導(dǎo)入詳解的文章就介紹到這了,更多相關(guān)python中的import內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • python簡單文本處理的方法

    python簡單文本處理的方法

    這篇文章主要介紹了python簡單文本處理的方法,涉及Python針對文本文件及字符串操作的相關(guān)技巧,需要的朋友可以參考下
    2015-07-07
  • Python+Tkinter制作猜燈謎小游戲

    Python+Tkinter制作猜燈謎小游戲

    元宵節(jié),又稱上元節(jié)、燈節(jié),是春節(jié)之后的第一個重要節(jié)日。而元宵節(jié)除了吃元宵、看花燈,還有一件最重要的事情就是猜燈謎!因此本文將通過Python Tkinter制作一個猜燈謎小游戲,感興趣的小伙伴可以了解一下
    2022-02-02
  • python3實(shí)現(xiàn)飛機(jī)大戰(zhàn)

    python3實(shí)現(xiàn)飛機(jī)大戰(zhàn)

    這篇文章主要為大家詳細(xì)介紹了python3實(shí)現(xiàn)飛機(jī)大戰(zhàn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-11-11
  • python中__new__和__init__的實(shí)現(xiàn)

    python中__new__和__init__的實(shí)現(xiàn)

    在Python中,每個對象都有兩個特殊的方法__new__和__init__,本文主要介紹了python中__new__和__init__的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-05-05
  • Python中的CURL PycURL使用例子

    Python中的CURL PycURL使用例子

    這篇文章主要介紹了Python中的CURL PycURL使用例子,需要的朋友可以參考下
    2014-06-06
  • Python自定義函數(shù)定義,參數(shù),調(diào)用代碼解析

    Python自定義函數(shù)定義,參數(shù),調(diào)用代碼解析

    這篇文章主要介紹了Python自定義函數(shù)定義,參數(shù),調(diào)用代碼解析,具有一定借鑒價(jià)值,需要的朋友可以參考下。
    2017-12-12
  • Django認(rèn)證系統(tǒng)user對象實(shí)現(xiàn)過程解析

    Django認(rèn)證系統(tǒng)user對象實(shí)現(xiàn)過程解析

    這篇文章主要介紹了Django認(rèn)證系統(tǒng)user對象實(shí)現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • Python實(shí)現(xiàn)注冊、登錄小程序功能

    Python實(shí)現(xiàn)注冊、登錄小程序功能

    本文通過實(shí)例代碼給大家介紹了Python實(shí)現(xiàn)登錄、注冊小程序功能,代碼簡單易懂非常不錯,具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2018-09-09
  • Python通過requests模塊實(shí)現(xiàn)抓取王者榮耀全套皮膚

    Python通過requests模塊實(shí)現(xiàn)抓取王者榮耀全套皮膚

    只學(xué)書上的理論是遠(yuǎn)遠(yuǎn)不如實(shí)踐帶來的提升快,只有在實(shí)例中才能獲得能力的提升,本篇文章手把手帶你用Python實(shí)現(xiàn)抓取王者榮耀全套皮膚,大家可以在過程中查缺補(bǔ)漏,提升水平
    2021-10-10
  • python os.system執(zhí)行cmd指令代碼詳解

    python os.system執(zhí)行cmd指令代碼詳解

    在本篇文章里小編給大家整理的是一篇關(guān)于python os.system執(zhí)行cmd指令代碼詳解內(nèi)容,有興趣的朋友們可以學(xué)習(xí)下。
    2021-10-10

最新評論