2016-01-29 28 views
1

我有以下的配置文件結構:Python的導入庫模擬「從XXX進口*」

app 
    \config 
    \development 
     \__init__.py 
     \settings.py 
     \app_config.py 
    \production 
     \__init__.py 
     \settings.py 
     \app_config.py 
    \testingpy 
     \settings.py 
     \app_config.py 
    \settinngs.py 
    \app_config.py 

其實app.config.settings只檢查環境變量RUNTIME_ENV(這可能是development|production|testing,相當於config的一個子文件夾)並加載相應的設置。

我只知道大約有importlib這回我模塊作爲局部變量導入和我被迫寫類似的東西:

SCALA_URL = imported_settings.SCALA_URL 
REDIS_URL = imported_settings.REDIS_URL 
SOME_SETTINGS_VAR = imported_settings.REDIS_URL 
.... tons of duplicated strings here, i.e. variables names are the same ... 

有沒有辦法做到類似python的表達的東西:from config.${RUNTIME_ENV}.settings import *

回答

2

globals()的返回值是可變的。你可以這樣做:

imported_foo = importlib.import_module('foo') 
globals().update(vars(imported_foo)) 

請注意,這會將下劃線前綴的內容導入到全局名稱空間中。如果你想排除這些,寫一個字典理解,只包括你想要的東西。例如:

globals().update({name: value 
        for name, value in vars(imported_foo).items() 
        if not name.startswith('_')}) 

locals(),它返回一個只讀值工作。這樣做(import *進入非全局名稱空間)是不合理的,因爲Python必須在編譯時知道所有局部變量的名稱,以便在字節碼中生成正確的LOAD_FOO指令(以及其他各種其他有趣的問題,例如識別由closure捕獲的變量)。你會發現,import *是一個函數或類中非法:

>>> def foo(): 
...  from foo import * 
... 
    File "<stdin>", line 1 
SyntaxError: import * only allowed at module level 
>>> 

這不僅僅是一個事情「import *是糟糕的設計。」這是一個基本的語言限制,不能用importlib解決。