有關python模組匯入機制的思考

2021-09-24 10:48:28 字數 3983 閱讀 4778

在pycharm上優化畢業設計demo的時候,發現一句話:

from tensorflow.nn import conv2d
其中nnconv2d均被警告,查其定義均顯示』「cannot find declaration to go to」。但是相關**確實能夠正常執行,且沒有報錯。

為了找到原因,嘗試人工尋找conv2d方法。

先找到tensorflow模組中的__init__.py,其中有這樣一行:

from tensorflow._api.v1 import nn
在此進一步尋找到nn模組的__init__.py檔案,並發現了這樣一行:

from tensorflow.python.ops.gen_nn_ops import conv2d
gen_nn_ops.py下確實找到了conv2d這一方法。

到此,說明了兩件事:

確實存在conv2d這一方法,並且程式執行時執行的應該就是該方法。(驗證過程省略)

既然能夠成功找到這一方法,為什麼pycharm會報錯,不能直接定位該方法?

根據以上的分析,現提出乙個猜想:在上述情況下,pycharm找不到相關方法或模組,會發出警告,但是程式在執行時會根據from tensorflow._api.v1 import nnfrom tensorflow.python.ops.gen_nn_ops import conv2d找到相關方法或模組。為了驗證這一猜想,開始復現問題。

首先分析一下tensorflow模組的結構,如下:

現復刻以上結構,加入到自己的專案,如下:

a.py

其中bp的初始化模組仿照tensorflow

from bp._api.v1 import nn

_apiv1的初始化模組與**保持一致,為空。

nn的初始化模組中補上乙個函式func_b以替代conv2d

def

func_b

(text)

:print

(text)

a.py負責測試,寫上:
from bp.nn import func_b

func_b(

'this is a.'

)

到此,內容和結構復現完成,開始測試。

測試結果如下:

pycharm在nnfunc_b上均出現警告資訊,符合猜想。

執行a.py,系統報錯,不符合猜想:

no module named 'bp.nn'

據此可知,系統並不能根據from tensorflow._api.v1 import nnfrom tensorflow.python.ops.gen_nn_ops import conv2d找到相關模組和方法,猜想是錯的。

由此,目前需要解決兩個問題:

既然from tensorflow._api.v1 import nn不能讓程式找到nn模組,那麼它的意義在哪?

程式在執行時是如何找到nn這一模組,進而尋找到conv2d這一方法的?

在嘗試修改a.py後,第乙個問題得到了解答:

from bp import nn

nn.func_b(

'this is a.'

)

執行上述**,不僅pycharm沒有出現警告,程式也正常執行。若注釋from bp._api.v1 import nn,上述**將會報錯。

這說明:bp的初始化模組中加入from bp._api.v1 import nn,可以讓其他程式能夠直接從bp中匯入nn模組。如果不加,那麼其他程式需要從bp._api.v1中匯入nn模組。

如果將程式尋找nn模組和conv2d方法所需要的資訊串比作一條「路」,那麼我們不難知道:

復現失敗,說明這條「路」不在當前的程式中;

復現成功,說明這條「路」在當前的程式中。

由於第一次復現失敗,說明這條「路」不在第一次復現的程式中。為了找到這條「路」,目前所需要做的是:保證能夠成功復現問題,使復現程式包含這條「路」。然後進一步簡化資訊,找出哪一部分**充當了這條「路」。處理步驟如下:

首先保證復現成功:將原tensorflow整包拷貝到test資料夾下,代替原來的bp包。為了防止衝突,將原tensorflow包名改為_tensorflow

在拷貝之後,pycharm出現警告,執行a.py,沒有報錯。復現成功。

將注意力集中在tensorflow的初始化模組上。將它的其它內容全部刪除,僅留下:

from tensorflow._api.v1 import nn
執行a.py,系統報錯:no module named 'tensorflow.nn'。說明「路」在刪除的資訊中。

還原tensorflow的初始化模組,依次注釋每乙個模組,找到了根源:

# make sure directory containing top level submodules is in

# the __path__ so that "from tensorflow.foo import bar" works.

)# pylint: disable=undefined-variable

if _tf_api_dir not

in __path__:

因此總結如下:

一般而言,在from xx.*** import ***x中,***需要在xx模組的__path__中。一般情況下,__path__為當前所在目錄,可以往裡新增新的目錄。

為了驗證上述結論,在第一次復現的基礎上,修改bp的初始化模組:

from bp._api.v1 import nn

print

(__path__)))

print

(__path__)

a.py中,pycharm對nnfunc_b提出警告,程式執行成功。列印結果如下:

[

'c:\\users\\zhazha\\desktop\\test\\bp'][

'c:\\users\\zhazha\\desktop\\test\\bp'

,'c:\\users\\zhazha\\desktop\\test\\bp\\_api\\v1'

]this is a.

python 的模組匯入

模組 就是一些函式和類的集合檔案,它能實現一些相應的功能,可以想象成匯入到python中以增強功能的擴充套件。需要使用特殊的命令import匯入以後才能使用。匯入模組的時候可以使用 import somemodule 按照 module.function 的格式使用函式,需要加模組名 from so...

python模組的匯入

用於指定包中的模組名 如 import pack1.module1 from pack1.module1 import fun1錯誤使用 import pack1.module1.fun1 from pack1 import module1.fun1將乙個模組中包含的變數匯入到當前模組的作用域內,共...

python模組的匯入

模組的匯入的方式有以下多種 1.import 模組名 2.import 模組名 as 別名 3.impoert 模組名1,模組名2.一行多個模組 4.from import 5.from import as 別名 6.from import 匯入所有 import time print time.t...