在 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...