不恰當的 import 會導致的問題

2021-10-07 18:54:26 字數 3599 閱讀 6474

在 python 中,import 語句會被執行,也就是在匯入某個模組的的類、函式等時候,會執行該模組,此時如果該模組中有例項化的物件或者可以執行的函式,那麼就會執行。用乙個工作中遇到的問題來解釋:

(關於業務的描述可以忽略)在執行工裝測試套時,正確填寫好需要測試的工裝ipc的資訊後,發現實際執行的是預設的ip值是device_info.json檔案中預設值,而不是當時需要測試的203.1.2.35。

在 pycharm 本地除錯 main_tooling.py,發現是乙個導包問題導致的:引入了乙個類的例項化(業務:破解裝置二層的模組)。

解決過程:

首先是複製console列印日誌中的「檢視update -v異常」,到utest工程中全域性查詢,發現只有在破二層的地方出現,於是在這邊新增斷點:

通過debug可以回溯前面呼叫的地方:

通過 git 歷史提交記錄發現是同事處理某個問題時引入:

通過回溯回顧,發現:

在最初執行的main_tooling.py中呼叫liveoperator模組中的類 :

from src.components.liveoperator import liveoperator
liveoperator.py中呼叫videoaction模組中的類 :

from src.components.videoaction import videoactionlapi
videoaction.py中呼叫video_parameters模組中的類:

from src.parameters.video_parameters import videoparameters
video_parameters.py中例項化了videoparameters類:

videoparameters = videoparameters(

)

在例項化過程中,就出現了問題的原因所在,拋開業務來說就是在不合適的時機,例項化了我不想例項化的類,我還沒做 *** 呢,你現在就給我例項化,我不能讓你這麼做。

解決辦法:

可以在將main_tooling.py中匯入liveoperator 的**放入需要執行的地方,而不是放在檔案的首部,這樣可以等到我做了某一業務操作後再執行匯入就沒有問題了,也就是乙個先後問題。

python 是可以迴圈引用的,只要迴圈引用中的模組並不是在定義階段就馬上使用:

# module1.py

import module2

class

moduledemo()

:def

module2_func

(self)

:print

(module2.module2_func)

# module2.py

import module1

defmodule2_func()

:print

(module1.moduledemo)

由於示例中只有在函式內部使用,只要 import 階段沒有執行到相應的用到 import 位置的**就沒有問題。正常使用時要避免三種使用方法:

from … import … (如果有迴圈匯入的,考慮把這種形式的去掉)

直接執行的** (避免匯入直接執行的**)

類的繼承(避免基類的模組去 import 派生類的模組)

還有其他方法:用到時再匯入,而不是放在模組頂部。比如將 import 放到函式裡面,可以解決問題,但治標不治本,治本的還是要重新劃分模組,邏輯理順了就不會出現迴圈 import 。

錯誤示範,出現 importerror:

# module1.py

from module2 import module2_func

class

moduledemo()

:def

module2_func

(self)

:print

(module2_func)

# module2.py

from module1 import moduledemo

defmodule2_func()

:print

(moduledemo)

reference

假設有以下模組:

foo.py:

from bar import bar_var

foo_var =

1

bar.py:

from foo import foo_var

bar_var =

2

問題在於直譯器將執行以下步驟:

最後一步失敗了,因為 python 尚未完成解釋foo,並且的全域性符號字典foo仍然為空。

同樣的事情會發生:使用import foo,然後在全域性**中訪問foo.foo_var

foo.py:

import bar

foo_var =

1

bar.py:

import foo

bar_var =

2print

(foo.foo_var)

執行 bar.py 會出現attributeerror: module 'foo' has no attribute 'foo_var'

guido van rossum 建議避免使用from import ...的所有用法,並將所有**放在函式中。全域性變數和類變數的初始化應僅使用常量或內建函式。這意味著來自匯入模組的所有內容都被引用為.

jim roskind建議在每個模組中按以下順序執行步驟:

van rossum 不太喜歡這種方法,因為這種匯入語句會出現在乙個奇怪的地方,但是也確實可行。

matthias urlichs建議重組**,這樣一開始就不需要遞迴匯入(迴圈匯入)。

以上這些解決方案不是互斥的。

reference

static的不恰當應用

最近總是和static鬧彆扭,看下面這個例子 取自我客戶的乙個例子 using system using system.threading namespace statictest public class database private static void close public stat...

針對CRM的兩種不恰當論調

一直以來,市場上對crm都存在著兩種不恰當的論調。一種是悲觀論,也就是失敗論,說企業實施crm這個失敗率太高了,甚至還有人列舉數字說有70 的都不成功 另一種是天真論,盲目樂觀,說只要上了crm,客戶就會滿意了,銷售就會提高了,小公司也敢跨國集團了。力點說,這兩種論調都是不可取的,首先crm是一種工...

python 不細心導致的error

一 列表問題 l 1,2,3,4 print lnone 該方法無返回值,但是會修改原來的列表。二 函式傳參 要明白哪些是可變型別 list 可變 coding utf 8 defread lst x print read lst lst return lstif name main lst 1,2...