Вопрос

Я пытаюсь динамически загружать созданные мной модули.

Сейчас это работает правильно:

import structures.index

Но если я попробую то же самое, импортировав его динамически, это не удастся.

struct = __import__("structures.index")

Предоставленная ошибка:

Error ('No module named structures.index',)

Есть идеи, почему?


Редактировать:При использовании полной области (это вроде работает?):

struct = __import__("neoform.structures.index")

Это не вызывает никаких ошибок, однако не загружает индексный модуль, а вместо этого загружает модуль «neoform».

Результат «struct»:

<module 'neoform' from '/neoform/__init__.py'>

Кроме того, в качестве побочного вопроса: как мне затем создать экземпляр класса внутри динамически загружаемого модуля?(при условии, что все модули содержат общее имя класса).

Редактировать:Решение:(спасибо coonj и Рику) В итоге это сработало.Не знаю почему (пока), но fromlist очевидно, должно было быть что-то «что угодно», поскольку это сработало, когда я поставил букву «а» в качестве значения (странно, учитывая, что в файле был только 1 класс).

def get_struct_module(self, name):
    try:
        return = __import__("neoform.structures." + name, fromlist='*')
    except ImportError, e:
        self.out.add("Could not load struct: neoform.structure." + name + "\n\n" + "Error " + str(e.args))
Это было полезно?

Решение

Я не уверен, что означает «это не удалось», поэтому просто упомяну об этом. __import__('structures.index') на самом деле должно работать, но оно не присваивает имя модуля в текущей области.Чтобы сделать это (а затем использовать класс в динамически импортируемом модуле), вам придется использовать:

structures = __import__('structures.index')
structures.index.SomeClass(...)

Полная информация о __import__ доступны здесь.

Редактировать:(на основе редактирования вопроса)

Импортировать neoform.structures.index, и верните index модуль, вы должны сделать следующее:

structures = __import__('neoform.structures.index', 
                        fromlist=['does not in fact matter what goes here!'])

Итак, если у вас есть список имен пакетов packages, вы можете импортировать их index модули и создать экземпляры некоторых MyClass класс для каждого, используя следующий код:

modules = [ __import__('neoform.%s.index' % pkg, fromlist=['a']) 
            for pkg in packages ]
objects = [ m.MyClass() for m in modules ]

Другие советы

Чтобы импортировать подмодули, вам необходимо указать их в поле fromlist аргумент __import__()
Например, эквивалент:

import structures.index

является:

structures = __import__('structures', fromlist=['index'])

Сделать это на карте немного сложнее...

import mod1.index
import mod2.index
import mod3.index

Для этого импорта вам нужно определить новую функцию, чтобы получить index субмодуль из каждого модуля:

def getIndexMods(mod_names):
  mod_list = map(lambda x: __import__(x, fromlist='index'))
  index_mods = [mod.index for mod in mod_list]
  return index_mods

Теперь вы можете сделать это, чтобы получить ссылки на все индексные модули:

index_mods = getIndexMods(['mod1', 'mod2', 'mod3'])

Кроме того, если вы хотите получить подмодули, которые не называются «индекс», вы можете сделать это:

mod1, mod2, mod3 = map(lambda x,y: __import__(x, fromlist=y), 
  ['mod1', 'mod2', 'mod3'], ['index1', 'index2', 'index3'])

Используйте полную область действия («neoform.structures.index») с этим вспомогательным методом.

def import_module(name):
    mod = __import__(name)
    components = name.split('.')
    for comp in components[1:]:
        mod = getattr(mod, comp)
    return mod

module = import_module("neoform.structures.index")
# do stuff with module

Java-программист здесь, но я думаю, вам нужен модуль имп

>>> import imp
>>> fm = imp.find_module('index', ['./structures']) # for submodule
>>> mymod = imp.load_module('structures.index', *fm)
>>> mymod
<module 'structures.index' from './structures/index.pyc'>
>>> x = mymod.insideIndex()
Initialising index class...

Вуаля!

С какой стати тебе заменить

import structures.index

с

map(__import__, ["structures.index"])

Первый (а) работает, (б) является динамический и (c) поддерживается напрямую.Какой возможный вариант использования существует для замены легко изменяемого исходного текста в виде простого текста чем-то более сложным?

Суммируя:не делай этого.Это не имеет никакой ценности.


Редактировать

«Я получаю импорт из базы данных» — это благородное усилие, но все же неразумное.Какой блок кода зависит от этого импорта?Весь этот блок кода — импорт и все такое — это то, что вы хотите выполнить.Весь этот блок кода — импорт, инструкции и все остальное — должен быть обычным старым файлом модуля Python.

Импортируйте этот блок кода из файловой системы.Используйте базу данных, чтобы определить, какой файл, автора файла — все, для чего вы хотите использовать базу данных.Но просто импортируйте и запустите модуль самым простым способом.

Действительно поздно постить здесь.Но я искал этот вопрос в Google.Я сделал несколько проб и ошибок.Не уверен, что этот фрагмент поможет, но вот он.Использование его для сайта Flask.

modules = ['frontend', 'admin']
for module in modules:
    mod = __init__('controllers.%s' % module, fromlist=[module])
    app.register_blueprint(mod.blueprint_mod)


# or
from importlib import import_module
modules = ['frontend', 'admin']
for module in modules:
    mod = import_module('controllers.%s' % module)
    app.regitster_blueprint(mod.blueprint_mod)
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top