Python: как сделать глобальный импорт из функции

Я боюсь, что это грязный способ подойти к проблеме, но...

скажем, что я хочу сделать некоторые импортные данные в Python на основе некоторых условий.

По этой причине я хочу написать функцию:

def conditional_import_modules(test):
    if test == 'foo':
        import onemodule, anothermodule
    elif test == 'bar':
        import thirdmodule, and_another_module
    else:
        import all_the_other_modules

Теперь, как я могу импортировать модули по всему миру?

Например:

conditional_import_modules(test='bar')
thirdmodule.myfunction()

Ответ 1

Импортированные модули - это просто переменные - имена, привязанные к некоторым значениям. Итак, все, что вам нужно, это импортировать их и сделать их глобальными с помощью ключевого слова global.

Пример:

>>> math
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'math' is not defined
>>> def f():
...     global math
...     import math
...
>>> f()
>>> math
<module 'math' from '/usr/local/lib/python2.6/lib-dynload/math.so'>

Ответ 2

Вы можете сделать импорт глобальным внутри такой функции:

def my_imports(module_name):
    globals()[module_name] = __import__(module_name)

Ответ 3

Вы можете вернуть эту функцию именам модулей, которые вы хотите импортировать, а затем использовать

mod == __import__(module_name)

Ответ 4

Вы можете использовать встроенную функцию __import__, чтобы условно импортировать модуль с глобальной областью.

Чтобы импортировать модуль верхнего уровня (подумайте: import foo):

def cond_import():
  global foo
  foo = __import__('foo', globals(), locals()) 

Импорт из иерархии (подумайте: import foo.bar):

def cond_import():
  global foo
  foo = __import__('foo.bar', globals(), locals()) 

Импорт из иерархии и псевдонима (think: import foo.bar as bar):

def cond_import():
  global bar
  foo = __import__('foo.bar', globals(), locals()) 
  bar = foo.bar

Ответ 5

Мне нравится подход @badzil.

def global_imports(modulename,shortname = None, asfunction = False):
    if shortname is None: 
        shortname = modulename
    if asfunction is False:
        globals()[shortname] = __import__(modulename)
    else:        
        globals()[shortname] = eval(modulename + "." + shortname)

Итак, что-то традиционно в модуле класса:

import numpy as np

import rpy2
import rpy2.robjects as robjects
import rpy2.robjects.packages as rpackages
from rpy2.robjects.packages import importr

Может быть преобразован в глобальную область:

global_imports("numpy","np")

global_imports("rpy2")
global_imports("rpy2.robjects","robjects")
global_imports("rpy2.robjects.packages","rpackages")
global_imports("rpy2.robjects.packages","importr",True)

Могут быть некоторые ошибки, которые я проверю и обновлю. В последнем примере также может быть псевдоним, который будет другим "shortname" или взломом типа "importr | aliasimportr"