Подтвердить что ты не робот

Как 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), потому что он живет в модуле, который нуждается в настройках .py.

4b9b3361

Ответ 1

Так как Django 1.7 существует простая функция для этого. Например:

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

Вы также можете получить классы из модуля:

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

Ответ 2

Взгляните в 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(). Я еще не знаю, если можно оценить из объекта функции какие аргументы он принимает. Я так подозреваю, но это отдельный вопрос (возможно, уже ответил?).