Импортировать все (*) динамически из модуля - PullRequest
22 голосов
/ 07 ноября 2010

У меня есть модуль Python, который я хочу динамически импортировать, учитывая только строку имени модуля. Обычно я использую importlib или __import__, и это работает довольно хорошо, учитывая, что я знаю, какие объекты я хочу импортировать из модуля, но есть ли способ сделать эквивалент import * динамически. Или есть лучший подход?

В целом я знаю, что использовать import * - плохая практика, но модули, которые я пытаюсь импортировать, автоматически генерируются на лету, и у меня нет возможности узнать, какой именно модуль содержит класс, к которому я обращаюсь. 1007 *

Спасибо.

Ответы [ 3 ]

24 голосов
/ 24 декабря 2010

Используйте update для диктов:

globals().update(importlib.import_module('some.package').__dict__)

Обратите внимание, что использование a_module.__dict__ отличается от from a_module import *, поскольку все имена "импортированы", а не только имена из __all__ или не начинаются с _.

5 голосов
/ 07 ноября 2010

Я придумал некрасивый хакерский код, он работает в Python 2.6. Я не уверен, что это самая умная вещь, которую можно сделать, хотя, возможно, некоторые другие люди здесь имеют некоторое понимание:

test = __import__('os',globals(),locals())
for k in dir(test):
    globals()[k] = test.__dict__[k]

Возможно, вы хотите поставить здесь галочку, чтобы убедиться, что вы ничего не перезаписываете в глобальном пространстве имен. Возможно, вы могли бы избежать части глобальных переменных и просто просмотреть каждый динамически импортируемый модуль для вашего класса интересов. Возможно, это было бы намного лучше, чем загрязнять глобальное пространство имен всем, что вы импортируете.

Например, скажем, ваш класс назван Request from urllib2

test = __import__('urllib2',globals(),locals())
cls = None
if 'Request' in dir(test):
    cls = test.__dict__['Request']
    # you found the class now you can use it!
    cls('http://test.com')
3 голосов
/ 16 июня 2016

Следующие слова очень греховны и обрекают вас на чистилище или еще хуже

# module A
myvar = "hello"

# module B
import inspect
def dyn_import_all(modpath):
  """Incredibly hackish way to load into caller's global namespace"""
  exec('from ' + modpath + ' import *', inspect.stack()[1][0].f_globals)

# module C
from module B import dyn_import_all
def print_from(modpath):
  dyn_import_all(modpath)
  print(myvar)
...