2010-09-09 62 views
11

我想了解關於django的另一個神奇的事情:它可以將字符串轉換爲模塊。django如何將字符串轉換爲模塊

settings.py中,INSTALLED_APPS聲明那樣:

INSTALLED_APPS = (
    'django.contrib.auth', 
    'django.contrib.contenttypes', 
    'django.contrib.sessions', 
) 

它包含所有的字符串。但django會將這些字符串轉換爲模塊並稍後導入它們。

我希望能做同樣的事情。但我不知道如何。 我有渲染調度的字典中settings.py:

RESOUCE_RENDERER = { 
    'video': 'video_player', 
    'audio': 'audio_player', 
} 

我以後要使用這樣的:RESOURCE_RENDERER['video'](MyVideo)

我不能直接分配函數名稱(例如video_player),因爲它位於需要settings.py的模塊中。

回答

8

由於Django 1.7有a simple function for this。例如:

from django.utils.module_loading import import_string 
my_module = import_string('path.to.my_module') 

您也可以從模塊獲取類:

MyClass = import_string('path.to.my_module.MyClass') 
8

採取django.conf.__init__.py看看,但基本上它使用importlib像這樣:

try: 
    mod = importlib.import_module(self.SETTINGS_MODULE) 
except ImportError, e: 
    raise ImportError("Could not import settings '%s' 
       (Is it on sys.path? Does it have syntax errors?): 
       %s" % (self.SETTINGS_MODULE, e)) 

# Settings that should be converted into tuples if they're mistakenly entered 
# as strings. 
tuple_settings = ("INSTALLED_APPS", "TEMPLATE_DIRS") 

編輯:在OP的要求,我已經擴大了榜樣,貢獻了一些下面。

現在,假設你有一個模塊中的函數列表,例如函數列表FUNCTIONS TO CALL中定義的函數列表。然後,你可以這樣打電話:

ARGUMENTS = '()' 

for FUNCTION in FUNCTIONS_TO_CALL: 
    function_string = FUNCTION + ARGUMENTS 
    exec(function_string) 

這假設每個函數都有相同的一組定義參數。您可以使用if語句來檢測用戶列出的函數名稱,並根據它是什麼提供自定義參數。你也可以通過閱讀python文件來評估參數應該是什麼。

您也可以在調用exec()eval()前查看模塊對象是否存在(我認爲這是可能的,我不知道)是否存在該函數。我不知道,如果可以從函數對象評估它需要什麼參數。我懷疑是這樣,但這是一個單獨的(可能已經回答?)問題。

+0

@Ninefingers,這會有所幫助,但我期待導入功能,而不僅僅是模塊。你知道我能做到嗎? – maroxe 2010-09-09 01:52:36

+0

我猜__import__是我正在尋找 – maroxe 2010-09-09 01:55:12

+0

是的,沒有。 import語句是importlib函數的一個包裝,因此,當您有趣的import_module時,您*已*導入了一個變量模塊*,就好像*您要求「import somevariable」一樣。我不認爲你可以'輸入'變量名,但你可以通過這個庫。現在,一旦你導入了一個模塊,你就可以訪問它的所有內容 - 我擴展了上面的例子,以包含從設置文件訪問'INSTALLED_APPS'的代碼,就像你在q中討論的那樣。 – 2010-09-09 01:59:01