国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

首頁(yè) 后端開(kāi)發(fā) Python教程 在 Python 中修復(fù)循環(huán)導(dǎo)入的不同方法

在 Python 中修復(fù)循環(huán)導(dǎo)入的不同方法

Nov 05, 2024 am 02:21 AM

你在Python中遇到過(guò)循環(huán)導(dǎo)入嗎?嗯,這是一種非常常見(jiàn)的代碼味道,表明設(shè)計(jì)或結(jié)構(gòu)有問(wèn)題。

循環(huán)導(dǎo)入示例

循環(huán)導(dǎo)入是如何發(fā)生的?當(dāng)兩個(gè)或多個(gè)相互依賴的模塊在完全初始化之前嘗試導(dǎo)入時(shí),通常會(huì)發(fā)生此導(dǎo)入錯(cuò)誤。

假設(shè)我們有兩個(gè)模塊:module_1.py 和 module_2.py。

# module_1.py
from module_2 import ModY
class ModX:
    mody_obj = ModY()
# module_2.py
from module_1 import ModX
class ModY:
    modx_obj = ModX()

在上面的代碼片段中,module_1和module_2都是相互依賴的。

module_1 中 mody_obj 的初始化依賴于 module_2,module_2 中 modx_obj 的初始化依賴于 module_1。

這就是我們所說(shuō)的循環(huán)依賴。兩個(gè)模塊在嘗試互相加載時(shí)都會(huì)陷入導(dǎo)入循環(huán)。

如果我們運(yùn)行 module_1.py,我們將得到以下回溯。

Traceback (most recent call last):
  File "module_1.py", line 1, in <module>
    from module_2 import ModY
  File "module_2.py", line 1, in <module>
    from module_1 import ModX
  File "module_1.py", line 1, in <module>
    from module_2 import ModY
ImportError: cannot import name 'ModY' from partially initialized module 'module_2' (most likely due to a circular import)

這個(gè)錯(cuò)誤說(shuō)明了循環(huán)導(dǎo)入的情況。當(dāng)程序嘗試從 module_2 導(dǎo)入 ModY 時(shí),當(dāng)時(shí) module_2 尚未完全初始化(由于另一個(gè)導(dǎo)入語(yǔ)句嘗試從 module_1 導(dǎo)入 ModX)。

如何修復(fù) Python 中的循環(huán)導(dǎo)入? ??有多種方法可以消除 Python 中的循環(huán)導(dǎo)入。

修復(fù) Python 中的循環(huán)導(dǎo)入

將代碼移至公共文件中

我們可以將代碼移動(dòng)到一個(gè)公共文件中以避免導(dǎo)入錯(cuò)誤,然后嘗試從該文件導(dǎo)入模塊。

# main.py ----> common file
class ModX:
    pass

class ModY:
    pass

在上面的代碼片段中,我們將類 ModX 和 ModY 移動(dòng)到一個(gè)公共文件 (main.py) 中。

# module_1.py
from main import ModY

class Mod_X:
    mody_obj = ModY()
# module_2.py
from main import ModX

class Mod_Y:
    modx_obj = ModX()

現(xiàn)在,module_1 和 module_2 從 main 導(dǎo)入類,修復(fù)了循環(huán)導(dǎo)入的情況。

這種方法有一個(gè)問(wèn)題,有時(shí)代碼庫(kù)太大,將代碼移動(dòng)到另一個(gè)文件中會(huì)存在風(fēng)險(xiǎn)。

將導(dǎo)入移至模塊末尾

我們可以將導(dǎo)入語(yǔ)句移到模塊末尾。這將為導(dǎo)入另一個(gè)模塊之前留出時(shí)間來(lái)完全初始化模塊。

# module_1.py
class ModX:
   pass

from module_2 import ModY

class Mod_X:
   mody_obj = ModY()
# module_2.py
class ModY:
   pass

from module_1 import ModX

在類/函數(shù)范圍內(nèi)導(dǎo)入模塊

在類或函數(shù)作用域內(nèi)導(dǎo)入模塊可以避免循環(huán)導(dǎo)入。這允許僅在調(diào)用類或函數(shù)時(shí)導(dǎo)入模塊。當(dāng)我們想要最小化內(nèi)存使用時(shí),它是相關(guān)的。

# module_1.py
class ModX:
  pass

class Mod_X:
   from module_2 import ModY
   mody_obj = ModY()
# module_2.py
class ModY:
   pass

class Mod_Y:
   from module_1 import ModX
   modx_obj = ModX()

我們分別將 import 語(yǔ)句移至 module_1 和 module_2 中的類 Mod_X 和 Mod_Y 范圍內(nèi)。

如果我們運(yùn)行 module_1 或 module_2,我們不會(huì)收到循環(huán)導(dǎo)入錯(cuò)誤。但是,這種方法使得類只能在類的范圍內(nèi)訪問(wèn),因此我們無(wú)法全局利用導(dǎo)入。

使用模塊名稱/別名

使用模塊名稱或僅像這樣的別名可以解決問(wèn)題。這允許兩個(gè)模塊通過(guò)將循環(huán)依賴推遲到運(yùn)行時(shí)來(lái)完全加載。

# module_1.py
from module_2 import ModY
class ModX:
    mody_obj = ModY()
# module_2.py
from module_1 import ModX
class ModY:
    modx_obj = ModX()

使用 importlib 庫(kù)

我們還可以使用 importlib 庫(kù)動(dòng)態(tài)導(dǎo)入模塊。

Traceback (most recent call last):
  File "module_1.py", line 1, in <module>
    from module_2 import ModY
  File "module_2.py", line 1, in <module>
    from module_1 import ModX
  File "module_1.py", line 1, in <module>
    from module_2 import ModY
ImportError: cannot import name 'ModY' from partially initialized module 'module_2' (most likely due to a circular import)
# main.py ----> common file
class ModX:
    pass

class ModY:
    pass

Python 包中的循環(huán)導(dǎo)入

通常,循環(huán)導(dǎo)入 來(lái)自同一包內(nèi)的模塊。在復(fù)雜的項(xiàng)目中,目錄結(jié)構(gòu)也很復(fù)雜,包內(nèi)包。

這些包和子包包含 __init__.py 文件,以提供更輕松的模塊訪問(wèn)。這就是有時(shí)無(wú)意中在模塊之間產(chǎn)生循環(huán)依賴的地方。

我們有以下目錄結(jié)構(gòu)。

# module_1.py
from main import ModY

class Mod_X:
    mody_obj = ModY()

我們有一個(gè) mainpkg 包和一個(gè) main.py 文件。我們?cè)?mainpkg 中有兩個(gè)子包 modpkg_x 和 modpkg_y。

這是 modpkg_x 和 modpkg_y 中每個(gè) Python 文件的樣子。

mainpkg/modpkg_x/__init__.py

# module_2.py
from main import ModX

class Mod_Y:
    modx_obj = ModX()

此文件從 module_1 和 module_1_1 導(dǎo)入兩個(gè)類(ModX 和 ModA)。

mainpkg/modpkg_x/module_1.py

# module_1.py
class ModX:
   pass

from module_2 import ModY

class Mod_X:
   mody_obj = ModY()

module_1 從 module_2 導(dǎo)入 ModY 類。

mainpkg/modpkg_x/module_1_1.py

# module_2.py
class ModY:
   pass

from module_1 import ModX

module_1_1 沒(méi)有導(dǎo)入任何內(nèi)容。它不依賴于任何模塊。

mainpkg/modpkg_y/__init__.py

# module_1.py
class ModX:
  pass

class Mod_X:
   from module_2 import ModY
   mody_obj = ModY()

此文件從 module_2 導(dǎo)入 ModY 類。

mainpkg/modpkg_y/module_2.py

# module_2.py
class ModY:
   pass

class Mod_Y:
   from module_1 import ModX
   modx_obj = ModX()

module_2 從 module_1_1 導(dǎo)入 ModA 類。

我們?cè)?main.py 文件中有以下代碼。

root_dir/main.py

# module_1.py
import module_2 as m2

class ModX:
    def __init__(self):
        self.mody_obj = m2.ModY()

主文件從 module_2 導(dǎo)入 ModY 類。該文件依賴于 module_2。

如果我們?cè)谶@里可視化導(dǎo)入周期,它看起來(lái)像下面忽略 modpkg_x 和 modpkg_y 中的 __init__.py 文件。

Different Ways to Fix Circular Imports in Python

我們可以看到主文件依賴于module_2,module_1也依賴于module_2,module_2又依賴于module_1_1。沒(méi)有導(dǎo)入周期。

但是你知道,模塊依賴于它們的 __init__.py 文件,因此 __init__.py 文件首先初始化,然后重新導(dǎo)入模塊。

Different Ways to Fix Circular Imports in Python

這就是現(xiàn)在的導(dǎo)入周期。

Different Ways to Fix Circular Imports in Python

這使得 module_1_1 依賴于 module_1,這是一個(gè)假依賴項(xiàng)。

如果是這種情況,清空子包 __init__.py 文件并使用單獨(dú)的 __init__.py 文件可以幫助在包級(jí)別集中導(dǎo)入。

# module_1.py
from module_2 import ModY
class ModX:
    mody_obj = ModY()

在此結(jié)構(gòu)中,我們?cè)?mainpkg 中添加了另一個(gè)子包 subpkg。

mainpkg/subpkg/__init__.py

# module_2.py
from module_1 import ModX
class ModY:
    modx_obj = ModX()

這將允許內(nèi)部模塊從單一來(lái)源導(dǎo)入,從而減少交叉導(dǎo)入的需要。

現(xiàn)在我們可以更新 main.py 文件中的導(dǎo)入語(yǔ)句。

root_dir/main.py

Traceback (most recent call last):
  File "module_1.py", line 1, in <module>
    from module_2 import ModY
  File "module_2.py", line 1, in <module>
    from module_1 import ModX
  File "module_1.py", line 1, in <module>
    from module_2 import ModY
ImportError: cannot import name 'ModY' from partially initialized module 'module_2' (most likely due to a circular import)

這解決了同一包內(nèi)模塊之間的循環(huán)依賴問(wèn)題。

結(jié)論

Python 中的循環(huán)依賴或?qū)胧且环N代碼異味,這表明需要對(duì)代碼進(jìn)行認(rèn)真的重構(gòu)和重構(gòu)。

您可以嘗試上述任何一種方法來(lái)避免 Python 中的循環(huán)依賴。


?如果您喜歡這篇文章,您可能還會(huì)感興趣

?Flask 中的模板繼承示例。

?exec() 和 eval() 之間的區(qū)別并舉例。

?了解Python中g(shù)lobal關(guān)鍵字的使用。

?Python 類型提示:函數(shù)、返回值、變量。

?為什么在函數(shù)定義中使用斜線和星號(hào)。

?學(xué)習(xí)率如何影響 ML 和 DL 模型?


現(xiàn)在就這些。

繼續(xù)編碼??。

以上是在 Python 中修復(fù)循環(huán)導(dǎo)入的不同方法的詳細(xì)內(nèi)容。更多信息請(qǐng)關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本站聲明
本文內(nèi)容由網(wǎng)友自發(fā)貢獻(xiàn),版權(quán)歸原作者所有,本站不承擔(dān)相應(yīng)法律責(zé)任。如您發(fā)現(xiàn)有涉嫌抄襲侵權(quán)的內(nèi)容,請(qǐng)聯(lián)系admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費(fèi)脫衣服圖片

Undresser.AI Undress

Undresser.AI Undress

人工智能驅(qū)動(dòng)的應(yīng)用程序,用于創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用于從照片中去除衣服的在線人工智能工具。

Clothoff.io

Clothoff.io

AI脫衣機(jī)

Video Face Swap

Video Face Swap

使用我們完全免費(fèi)的人工智能換臉工具輕松在任何視頻中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費(fèi)的代碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

功能強(qiáng)大的PHP集成開(kāi)發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺(jué)化網(wǎng)頁(yè)開(kāi)發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級(jí)代碼編輯軟件(SublimeText3)

熱門話題

Laravel 教程
1601
29
PHP教程
1502
276
如何處理Python中的API身份驗(yàn)證 如何處理Python中的API身份驗(yàn)證 Jul 13, 2025 am 02:22 AM

處理API認(rèn)證的關(guān)鍵在于理解并正確使用認(rèn)證方式。1.APIKey是最簡(jiǎn)單的認(rèn)證方式,通常放在請(qǐng)求頭或URL參數(shù)中;2.BasicAuth使用用戶名和密碼進(jìn)行Base64編碼傳輸,適合內(nèi)部系統(tǒng);3.OAuth2需先通過(guò)client_id和client_secret獲取Token,再在請(qǐng)求頭中帶上BearerToken;4.為應(yīng)對(duì)Token過(guò)期,可封裝Token管理類自動(dòng)刷新Token;總之,根據(jù)文檔選擇合適方式,并安全存儲(chǔ)密鑰信息是關(guān)鍵。

如何一次迭代兩個(gè)列表 如何一次迭代兩個(gè)列表 Jul 09, 2025 am 01:13 AM

在Python中同時(shí)遍歷兩個(gè)列表的常用方法是使用zip()函數(shù),它會(huì)按順序配對(duì)多個(gè)列表并以最短為準(zhǔn);若列表長(zhǎng)度不一致,可使用itertools.zip_longest()以最長(zhǎng)為準(zhǔn)并填充缺失值;結(jié)合enumerate()可同時(shí)獲取索引。1.zip()簡(jiǎn)潔實(shí)用,適合成對(duì)數(shù)據(jù)迭代;2.zip_longest()處理不一致長(zhǎng)度時(shí)可填充默認(rèn)值;3.enumerate(zip())可在遍歷時(shí)獲取索引,滿足多種復(fù)雜場(chǎng)景需求。

什么是Python迭代器? 什么是Python迭代器? Jul 08, 2025 am 02:56 AM

Inpython,IteratorSareObjectSthallowloopingThroughCollectionsByImplementing_iter __()和__next __()。1)iteratorsWiaTheIteratorProtocol,使用__ITER __()toreTurnterateratoratoranteratoratoranteratoratorAnterAnteratoratorant antheittheext__()

Python Fastapi教程 Python Fastapi教程 Jul 12, 2025 am 02:42 AM

要使用Python創(chuàng)建現(xiàn)代高效的API,推薦使用FastAPI;其基于標(biāo)準(zhǔn)Python類型提示,可自動(dòng)生成文檔,性能優(yōu)越。安裝FastAPI和ASGI服務(wù)器uvicorn后,即可編寫接口代碼。通過(guò)定義路由、編寫處理函數(shù)并返回?cái)?shù)據(jù),可以快速構(gòu)建API。FastAPI支持多種HTTP方法,并提供自動(dòng)生成的SwaggerUI和ReDoc文檔系統(tǒng)。URL參數(shù)可通過(guò)路徑定義捕獲,查詢參數(shù)則通過(guò)函數(shù)參數(shù)設(shè)置默認(rèn)值實(shí)現(xiàn)。合理使用Pydantic模型有助于提升開(kāi)發(fā)效率和準(zhǔn)確性。

如何用Python測(cè)試API 如何用Python測(cè)試API Jul 12, 2025 am 02:47 AM

要測(cè)試API需使用Python的Requests庫(kù),步驟為安裝庫(kù)、發(fā)送請(qǐng)求、驗(yàn)證響應(yīng)、設(shè)置超時(shí)與重試。首先通過(guò)pipinstallrequests安裝庫(kù);接著用requests.get()或requests.post()等方法發(fā)送GET或POST請(qǐng)求;然后檢查response.status_code和response.json()確保返回結(jié)果符合預(yù)期;最后可添加timeout參數(shù)設(shè)置超時(shí)時(shí)間,并結(jié)合retrying庫(kù)實(shí)現(xiàn)自動(dòng)重試以增強(qiáng)穩(wěn)定性。

Python函數(shù)可變范圍 Python函數(shù)可變范圍 Jul 12, 2025 am 02:49 AM

在Python中,函數(shù)內(nèi)部定義的變量是局部變量,僅在函數(shù)內(nèi)有效;外部定義的是全局變量,可在任何地方讀取。1.局部變量隨函數(shù)執(zhí)行結(jié)束被銷毀;2.函數(shù)可訪問(wèn)全局變量但不能直接修改,需用global關(guān)鍵字;3.嵌套函數(shù)中若要修改外層函數(shù)變量,需使用nonlocal關(guān)鍵字;4.同名變量在不同作用域互不影響;5.修改全局變量時(shí)必須聲明global,否則會(huì)引發(fā)UnboundLocalError錯(cuò)誤。理解這些規(guī)則有助于避免bug并寫出更可靠的函數(shù)。

如何用Python和Pandas解析HTML表 如何用Python和Pandas解析HTML表 Jul 10, 2025 pm 01:39 PM

是的,你可以使用Python和Pandas解析HTML表格。首先,使用pandas.read_html()函數(shù)提取表格,該函數(shù)可將網(wǎng)頁(yè)或字符串中的HTML元素解析為DataFrame列表;接著,若表格無(wú)明確列標(biāo)題,可通過(guò)指定header參數(shù)或手動(dòng)設(shè)置.columns屬性修復(fù);對(duì)于復(fù)雜頁(yè)面,可結(jié)合requests庫(kù)獲取HTML內(nèi)容或使用BeautifulSoup定位特定表格;注意JavaScript渲染、編碼問(wèn)題及多表識(shí)別等常見(jiàn)陷阱。

在Python中訪問(wèn)嵌套的JSON對(duì)象 在Python中訪問(wèn)嵌套的JSON對(duì)象 Jul 11, 2025 am 02:36 AM

在Python中訪問(wèn)嵌套JSON對(duì)象的方法是先明確結(jié)構(gòu),再逐層索引。首先確認(rèn)JSON的層級(jí)關(guān)系,例如字典嵌套字典或列表;接著使用字典鍵和列表索引逐層訪問(wèn),如data"details"["zip"]獲取zip編碼,data"details"[0]獲取第一個(gè)愛(ài)好;為避免KeyError和IndexError,可用.get()方法設(shè)置默認(rèn)值,或封裝函數(shù)safe_get實(shí)現(xiàn)安全訪問(wèn);對(duì)于復(fù)雜結(jié)構(gòu),可遞歸查找或使用第三方庫(kù)如jmespath處理。

See all articles