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()
5 ответов
импортированные модули - это просто переменные-имена, привязанные к некоторым значениям. Поэтому все, что вам нужно-это импортировать их и сделать их глобальный с 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'>
вы можете сделать импорт глобальным в такой функции:
def my_imports(module_name):
globals()[module_name] = __import__(module_name)
эта функция может возвращать имена модулей, которые вы хотите импортировать, а затем использовать
mod == __import__(module_name)
вы можете использовать встроенную функцию __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())
импорт из иерархии и псевдоним (кажется: import foo.bar as bar
):
def cond_import():
global bar
foo = __import__('foo.bar', globals(), locals())
bar = foo.bar
мне нравится подход @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"