2010-09-09 2 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") 

Редактировать: По просьбе ОП я расширил пример и способствовали некоторые более ниже.

Теперь предположим, что у вас есть список функций в этом модуле, определенный, например, в FUNCTIONS TO CALL, список функций. Затем вы можете назвать их следующим образом:

ARGUMENTS = '()' 

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

Это предполагает, что каждая функция имеет тот же набор определенных аргументов. Вы можете использовать оператор if для определения имени функции, указанного пользователем, и предоставления настраиваемых аргументов в зависимости от того, что это такое. Вы также можете оценить, прочитав файл python, какие должны быть аргументы.

Вы также можете проверить объект модуля на (предположим, это возможно, я не знаю), посмотрите, существует ли эта функция до вызова exec() или eval(). Я еще не знаю, если можно оценить из объекта функции какие аргументы он принимает. Я так подозреваю, но это отдельный вопрос (возможно, уже ответил?).

+0

@Ninefingers, это помогло бы, но я ищу, чтобы импортировать функции, а не только модули. Вы знаете, как я могу это достичь? – maroxe

+0

i guess __import__ - это то, что я ищу – maroxe

+0

Да и нет. Оператор import является средством для функций importlib, поэтому, когда вы хотите импортировать переменную module *, вы * импортировали переменный модуль *, как если бы вы запросили «import somevariable». Я не думаю, что вы можете «импортировать» имена переменных, но вы можете через эту библиотеку. Теперь, как только вы импортируете модуль, у вас есть доступ ко всему, что есть в нем, я расширил приведенный выше пример, чтобы включить код, доступ к «INSTALLED_APPS» из файла настроек, как вы обсуждали в q. – 2010-09-09 01:59:01

Смежные вопросы