Как я могу импортировать функцию модуля Python динамически? - PullRequest
17 голосов
/ 31 августа 2010

Предполагая, что my_function() находится в my_apps.views, я бы хотел импортировать my_function динамически, не используя что-то вроде exec или eval.

Есть ли в любом случае для этого.Я ищу что-то похожее на:

my_function = import_func("my_apps.views.my_function")

my_function()
   ... code is executed

Ответы [ 4 ]

24 голосов
/ 31 августа 2010

Вы хотите

my_function = getattr(__import__('my_apps.views'), 'my_function')

Если вам случится узнать имя функции во время компиляции, вы можете сократить это значение до

my_function = __import__('my_apps.views').my_function

Это загрузит my_apps.views, а затемприсвойте его my_function атрибут локальному my_function.

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

views = __import__('my_apps.views')
my_function = getattr(views, 'my_function')
my_other_function = getattr(views, 'my_other_function')
my_attribute = getattr(views, 'my_attribute')

, так как он более читабелен и экономит некоторые вызовы на __import__.Опять же, если вы знаете имена, код может быть сокращен, как указано выше.

Вы также можете сделать это с помощью инструментов из модуля imp , но это более сложно.

9 голосов
/ 31 августа 2010

Обратите внимание, что Python 2.7 добавил модуль importlib , удобные обертки для __import__() и функция обратного порта 3.1.

Этот модуль является вторым подмножеством того, что доступно в более полнофункциональном пакете с тем же именем из Python 3.1, который обеспечивает полную реализацию импорта. Что здесь предоставлено, чтобы облегчить переход с 2.7 на 3.1.

importlib.import_module(name, package=None)

Импорт модуля. Аргумент name указывает, какой модуль импортировать в абсолютном или относительном выражении (например, pkg.mod или ..mod). Если имя указано в относительных терминах, то пакет должен указывать аргумент пакета, который должен служить якорем для разрешения имени пакета (например, import_module ('.. mod', 'pkg.subpkg') будет импортировать pkg .mod). Указанный модуль будет вставлен в sys.modules и возвращен.

1 голос
/ 24 декабря 2014

Я только что написал этот код, и мне кажется, что это нужно многим, поэтому даже если позже я покажу его

def my_import(module_name,func_names = [],cache = False):
    if module_name in globals() and cache:
        return True
    try: 
        m = __import__(module_name, globals(), locals(), func_names, -1)
        if func_names:
            for func_name in func_names:
                globals()[func_name] = getattr(m,func_name)
        else:
            globals()[module_name] = m
        return True
    except ImportError:
        return False
def my_imports(modules):
    for module in modules:
        if type(module) is tuple:
            name = module[0]
            funcs = module[1]
        else:
            name = module
            funcs = []
        if not my_import(name, funcs):
             return module
    return ''

def checkPluginsImports(plugin,modules):
    c = my_imports(modules)
    if c:
        print plugin +" has errors!: module '"+c+"' not found"

# example: file test.py with "x" function
def d():
    checkPluginsImports('demoPlugin',[('test',['x'])])

d()
x()
0 голосов
/ 19 декабря 2016
def import_by_string(full_name):
    module_name, unit_name = full_name.rsplit('.', 1)
    return getattr(__import__(module_name, fromlist=['']), unit_name)


exists = import_by_string("os.path.exists")
...