1.簡介 在實際項目中,我們可能需要在執行代碼的過程中動態導入包並執行包中的相應內容,通常情況下,我們可能會將所需導入的包及對象以字元串的形式傳入,例如test.test.run,下麵將介紹如何動態導入。 假設存在如下包: 其中test.py的內容如下: count = 1 def run(): p ...
1.簡介
在實際項目中,我們可能需要在執行代碼的過程中動態導入包並執行包中的相應內容,通常情況下,我們可能會將所需導入的包及對象以字元串的形式傳入,例如test.test.run,下麵將介紹如何動態導入。
假設存在如下包:
其中test.py的內容如下:
count = 1
def run():
print("run")
下麵,我們將使用test.test2.run來動態導入run方法
一、使用內置的__import__方法導入相應的包
module = __import__(
"test2.test", globals=globals(), locals=locals(), fromlist=["run"]
)
print(module)
print(getattr(module, "run"))
print(getattr(module, "count"))
# 結果
<module 'test2.test' from 'c:\\Users\\ts\\Desktop\\日報\\2023.1.5\\test2\\test.py'>
<function run at 0x000002EC1CB9B250>
1
__import__(name,globals=None,locals=None,fromlist=(),level=0)-> module
含義:導入模塊。因為此函數是供Python解釋器使用的,而不是一般用途,所以最好使用importlib.import_module()
以編程方式導入模塊。
- name:需要導入的模塊的名稱,包含全路徑。
- globals: 當前範圍的全局變數,正常設置為globals()。
- locals:當前範圍的局部變數,正常不需要使用,設置為locals()。
- fromlist: 控制導入的包,例_import__('a.B',…)在fromlist為空時返回包a,但在fromlist不為空時,返回其子模塊B,理論上只要fromlist不為空,則導入的是整個的name的包。
- level:判斷路徑是絕對的還是相對的,0是絕對的,正數是相當於當前模塊要搜索的父目錄的數量。
二、使用importlib.import_module進行導入
from importlib import import_module
module = import_module(name="test2.test")
print(module)
print(getattr(module, "run"))
print(getattr(module, "count"))
import_module(name, package=None)
- name: 需要導入的包名。
- package: 需要相對導入的包名稱,目前發現設置package後,name只能設置package以內的內容,示例如下:
存在如下包
module = import_module(name="..test2", package="test3.test3")
print(module)
print(getattr(module, "run"))
print(getattr(module, "count"))
#學習中遇到問題沒人解答?小編創建了一個Python學習交流群:725638078
# 結果
<module 'test3.test2' from 'c:\\Users\\ts\\Desktop\\日報\\2023.1.5\\test3\\test2.py'>
<function run at 0x0000024665C00310>
1
上述結果導入了test3.test2,name只能設置package以內的包。
三、直接使用exec拼接代碼執行(不推薦)
str_data = "test2.test"
exec(
"import {} as t\n\
\
print(t.run())\n\
print(t.count)\n".format(
str_data
)
)
上述方式不推薦,其實就是相當於本地導入然後將代碼作為參數添加到exec的參數中。
補充
關於importlib模塊,還有一個方法我們需要去註意一下,就是reload方法,但我們在代碼執行過程中動態的修改了某個包的內容時,想要立即生效,可以使用reload方法去重載對應的包即可。