日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python中遇到循环import即circular import的问题原理剖析及解决方案

發(fā)布時間:2024/7/5 python 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python中遇到循环import即circular import的问题原理剖析及解决方案 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

在python中常常會遇到循環(huán)import即circular import的問題,今天主要給大家介紹了關(guān)于Python中循環(huán)引用(import)失敗的解決方法,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考借鑒。

一、前言

最近在開發(fā)智能家居項目項目中,由于代碼結(jié)構(gòu)層級劃分不合理,導致了循環(huán)引用(import)module失敗的問題,錯誤如下:

? File "./design_app/views.py", line 7, in <module>
? ? import alg.auto_design.evaluate as evaluate
? File "./alg/auto_design/evaluate.py", line 5, in <module>
? ? from alg.auto_design.helpers.json_io import json2fp
? File "./alg/auto_design/helpers/__init__.py", line 2, in <module>
? ? from alg.auto_design.helpers import json_io
? File "./alg/auto_design/helpers/json_io.py", line 14, in <module>
? ? from alg.auto_design.room_type.dingroom.base import DiningRoom
? File "./alg/auto_design/room_type/dingroom/base.py", line 13, in <module>
? ? from alg.auto_design_easyhome.utility import get_opposite_bounds
? File "./alg/auto_design_easyhome/utility.py", line 8, in <module>
? ? from alg.auto_design_easyhome.room_type.master_bedroom import \
? File "./alg/auto_design_easyhome/room_type/master_bedroom/__init__.py", line 3, in <module>
? ? from alg.auto_design_easyhome.room_type.master_bedroom.base import MainBedroom
? File "./alg/auto_design_easyhome/room_type/master_bedroom/base.py", line 6, in <module>
? ? from alg.auto_design_easyhome.helpers import extract_rec
? File "./alg/auto_design_easyhome/helpers/__init__.py", line 2, in <module>
? ? from alg.auto_design_easyhome.helpers import json_io
? File "./alg/auto_design_easyhome/helpers/json_io.py", line 14, in <module>
? ? from alg.auto_design_easyhome.room_type.dingroom.base import DiningRoom
? File "./alg/auto_design_easyhome/room_type/dingroom/base.py", line 13, in <module>
? ? from alg.auto_design_easyhome.utility import get_opposite_bounds
ImportError: cannot import name 'get_opposite_bounds' from partially initialized module 'alg.auto_design_easyhome.utility' (most likely due to a circular import) (./alg/auto_design_easyhome/utility.py)

二、import執(zhí)行過程

當我們import一個文件時,python會首先去查找這個文件之前是否被import過,如果這個文件之前有被import過,就不會重新再import一次。所以如果A模塊
代碼里import了B模塊,并且B模塊里又import了A模塊,python的執(zhí)行順序會變成這樣:

  • 開始執(zhí)行模塊A
  • 當A執(zhí)行到import B的地方,則停止執(zhí)行A模塊后面的代碼,轉(zhuǎn)而開始執(zhí)行B模塊的代碼
  • 當B模塊從頭執(zhí)行到import A的地方時,python此時并不會回過頭去接著執(zhí)行A剩余的代碼,而且將A模塊在中斷前已經(jīng)初始化的屬性全加載到B模塊中

三、原理

這個時候就有一個問題,當前腳本Main第一次執(zhí)行,需要執(zhí)行from A import ,發(fā)現(xiàn)沒有A,就新建一個A在內(nèi)存中,然后填充A模塊的信息,就會去執(zhí)行A,此時,A里面要 from Main import D,那么因為Main已被執(zhí)行,就直接從內(nèi)存的map中取得Main的信息,不過此時Main的信息還沒有填充完,因為之前就是為了填充才轉(zhuǎn)到A的,這時從已有的空的Main中拿不到D,就會報錯,ImportError。

四、解決方案

1、方案一 合理劃分項目代碼層級

循環(huán)引用最大的本質(zhì)問題是代碼層級結(jié)構(gòu)劃分的不合理,所以最根本的、最合理的解決方案就是重新劃分好代碼的層級結(jié)構(gòu),使其合理化,自然就規(guī)避了循環(huán)引用的麻煩。

2、方案二 只引用當前的包,不引用具體的模塊

如果你的代碼是這樣,那么這種方式是會奏效的。

案例一:修改前

# a.pyfrom B import bdef a():pass# some codes# b.pyfrom A import adef b():a.a()#some codes

案例一:修改后

# a.pyfrom B import bdef a():pass# some codes# b.pyimport Adef b():A.a.a()#some codes

2、方案二 將引用放到函數(shù)內(nèi)部

如果你的代碼是這樣,那么這種方式是會奏效的。

案例二:修改前

# a.pyfrom B import bdef a():pass# some codes# b.pyfrom A import adef b():a.a()#some codes

案例二:修改后

# a.pyfrom B import bdef a():pass# some codes# b.pydef b():from A import aa.a()#some codes

五、總結(jié)

只有理解了python在import時的工作原理,這種cicular import的問題才會很好的分析和解決。

總結(jié)

以上是生活随笔為你收集整理的python中遇到循环import即circular import的问题原理剖析及解决方案的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。