2017-06-12 117 views
8

正如討論的here,我們可以使用字符串變量動態地導入模塊。Python動態導入 - 如何從變量的模塊名稱中導入*

import importlib 
importlib.import_module('os.path') 

我的問題是如何從字符串變量import *

一些像這樣的事情沒有工作,現在

importlib.import_module('os.path.*') 
+1

你爲什麼要這麼做? ''''''進口通常是不被接受的,它們混亂了命名空間,你最終可能會導入你不想要的東西(例如,模塊被更新,獲得覆蓋先前導入的新函數)。你有動態地做這件事的具體用例嗎? – mata

+0

我知道用'import *'聽起來很危險;儘管它適用於簡單的用例。我的具體用例是,我試圖用'proboscis'來運行'python test',它允許我選擇運行哪個測試套裝 - 所選擇的測試套裝是由一組測試文件名定義的。 –

回答

14

你可以做下面的技巧:

>>> import importlib 
>>> globals().update(importlib.import_module('math').__dict__) 
>>> sin 
<built-in function sin> 

被警告,使所有的名稱可用的模塊在本地,所以它是略有不同比*,因爲它不是以__all__開始,所以對於例如它也將覆蓋__name__,__package__,__loader__,__doc__

更新:

這裏是@mata在comments指出了一個更精確,更安全的版本:

module = importlib.import_module('math') 

globals().update(
    {n: getattr(module, n) for n in module.__all__} if hasattr(module, '__all__') 
    else 
    {k: v for (k, v) in module.__dict__.items() if not k.startswith('_') 
}) 

特別感謝南摹VU的協助,讓答案更完整。

+0

我不明白'它與*有些不同,因爲它不以__all__開始 - 它是什麼**它在這裏? –

+2

這也會導入諸如'__name__','__package__','__loader__','__doc__'等你絕對不想導入的東西。 – mata

+5

不止是一個罪 – hurturk