2013-06-21 55 views
7

我們都被告知使用from module import *是一個壞主意。但是,有沒有辦法使用通配符導入module的內容的子集Python:通配符子集導入

例如:

module.py:

MODULE_VAR1 = "hello" 
MODULE_VAR2 = "world" 
MODULE_VAR3 = "The" 
MODULE_VAR4 = "quick" 
MODULE_VAR5 = "brown" 
... 
MODULE_VAR10 = "lazy" 
MODULE_VAR11 = "dog!" 
MODULE_VAR12 = "Now" 
MODULE_VAR13 = "is" 
... 
MODULE_VAR98 = "Thats" 
MODULE_VAR99 = "all" 
MODULE_VAR100 = "folks!" 

def abs(): 
    print "Absolutely useful function: %s" % MODULE_VAR1 

顯然,我們不希望使用from module import *因爲我們會被重寫abs功能。但是,假設我們希望所有的MODULE_VAR*變量都可以在本地訪問。

簡單地把from module import MODULE_VAR*不起作用。有沒有辦法做到這一點?

我用了100個變量作爲說明,因爲做from module import MODULE_VAR1, MODULE_VAR2, MODULE_VAR3, ..., MODULE_VAR100顯然會很難操作,而且如果增加了更多變量(例如MODULE_VAR101),它將不起作用。

回答

2

使用import *語法時,可以使用__all__變量導入特定變量。

mymodule.py

__all__ = [ 
    'MODULE_VAR1', 
    'MODULE_VAR2', 
    'MODULE_VAR3', 
    'MODULE_VAR4', 
    'MODULE_VAR5', 
] 

MODULE_VAR1 = "hello" 
MODULE_VAR2 = "world" 
MODULE_VAR3 = "The" 
MODULE_VAR4 = "quick" 
MODULE_VAR5 = "brown" 

def abs(): 
    print "Absolutely useful function: %s" % MODULE_VAR1 

然後我們可以正是如此使用它:

from mymodule import * 
print MODULE_VAR1 # hello 
print abs # <built-in function abs> 

當一個模塊使用*進口,Python的檢查模塊的__all__變量,它可以覆蓋哪些否則將被視爲模塊中的普通「公共」變量(這將是不以下劃線開頭的變量),並允許您明確定義哪些變量是「公開」的。 Check out this question

+0

這太棒了!但是,如果您無法控制模塊的源代碼,是否有辦法達到相同的效果? – seaotternerd

+0

對不起,我誤解了。我不知道有什麼辦法從本地導入另一個模塊的特定變量。但作爲一個非常簡單的解決方案,您可以創建一個幫助程序來導入模塊並遍歷模塊的屬性以提取所需的變量。在你的例子中,這將防止'abs'變量被覆蓋,你不會導入模塊變量,而是模塊本身。另外,你可以在函數範圍內導入模塊變量,以防止內置的'abs'函數被覆蓋。我認爲@jsbueno有一個完美的例子。 – kuujo

+0

我不知道你是否被誤解 - 我不是那個問這個問題的人,我只是好奇。謝謝! – seaotternerd

7

你可以有一個輔助函數,該函數 - ,它可以不用魔法來完成:

import re 

def matching_import(pattern, module, globals): 
    for key, value in module.__dict__.items(): 
     if re.findall(pattern, key): 
      globals[key] = value 

現在,你可以例如做:

from utils import matching_import 
import constants 

matching_import("MODULE_VAR.*", constants, globals()) 

在此使用globals()明確方式避免了幀內省魔法,這通常被認爲是有害的。

+0

好的解決方案。 +1 – kuujo