![](/img/trans.png)
[英]ModuleNotFoundError when using importlib.import_module
[英]Using importlib.import_module over an import statement
我使用的是 api -- smartsheet-python-sdk 從源代碼執行時運行良好。 但是,當我使用 PyInstaller 轉到 package 時,我遇到了一個錯誤,因為 PyInstaller 找不到必要的模塊。 在 smartsheet 庫中,它使用 importlib.import_module 從庫中導入模塊。
def __getattr__(self, name):
"""
Handle sub-class instantiation.
Args:
name (str): Name of smartsheet to instantiate.
Returns:
Instance of named class.
"""
try:
# api class first
class_ = getattr(importlib.import_module(
__package__ + '.' + name.lower()), name)
return class_(self)
except ImportError:
# model class next:
try:
class_ = getattr(importlib.import_module(
name.lower()), name)
return class_()
except ImportError:
self._log.error(
'ImportError! Could not load api or model class %s', name)
return name
當它只從自己的庫中導入模塊而不是僅僅將導入語句添加到已知模塊時,使用這樣的東西有什么客觀好處嗎?
從實際的角度來看,這種方法之所以有利有幾個不同的原因。
顯式列出模塊需要執行額外的步驟來集成新模塊。 聲明導入的這一步可以完全省略。
如果不經常添加新模塊,忘記在正確的位置導入模塊是可能發生的簡單小錯誤之一。 刪除該要求意味着不會發生錯誤。 這種方法會有其他缺點嗎? 當然,但這些權衡的重要性是主觀的。
在你寫的評論中
我只是不明白這種特殊情況需要這樣做的原因,因為它只會引用它自己的模塊。
這是一個錯誤的假設。 一個模塊完全有可能在未來某個時間點來自另一個位置。 不太可能? 也許吧,但這種設計允許更輕松地添加新的可能位置 - 這里使用了兩個位置,第三個當然是可能的。 例如,也許模擬用於測試目的。 當然還有其他方法可以工作,但這似乎是這種方法的一個可能原因。
最終,您是正確的,這種方法很難輕松加載到 PyInstaller 中。 從他們的文檔中,您可以將一些變通方法應用於構建過程的腳本。 (為方便起見,在此復制)
一些 Python 腳本以 PyInstaller 無法檢測到的方式導入模塊:例如,通過使用帶有可變數據的
__import__()
function、使用imp.find_module()
或在運行時操作sys.path
值。 如果你的腳本需要 PyInstaller 不知道的文件,你必須幫助它:
- 您可以在
pyinstaller
命令行上提供其他文件。- 您可以在命令行上提供其他導入路徑。
- 您可以編輯 PyInstaller 第一次為您的腳本運行它時編寫的
myscript.spec
文件。 在規范文件中,您可以告訴 PyInstaller 您的腳本獨有的代碼模塊。- 您可以編寫通知 PyInstaller 隱藏導入的“掛鈎”文件。 如果您為其他用戶也可能使用的 package 創建“掛鈎”,您可以將掛鈎文件貢獻給 PyInstaller。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.