У меня есть классы, для создания экземпляров которых требуются зависимости, но в остальном они не являются обязательными. Я хотел бы лениво импортировать зависимости и не создать экземпляр класса, если они недоступны. Обратите внимание, что эти зависимости не требуются на уровне пакета (в противном случае они были бы обязательными с помощью инструментов настройки). Сейчас у меня есть что-то вроде этого:
Код: Выделить всё
class Foo:
def __init__(self):
try:
import module
except ImportError:
raise ModuleNotFoundError("...")
def foo(self):
import module
Поскольку этот шаблон try/Exception является распространенным, я хотел бы абстрагировать его в ленивый импортер. В идеале, если модуль доступен, мне не нужно будет снова импортировать его в Foo.foo, поэтому я бы хотел, чтобы модуль был доступен после его импорта в __init__. Я попробовал следующее, которое заполняет globals() и не может создать экземпляр класса, если numpy недоступен, но это загрязняет глобальное пространство имен.
Код: Выделить всё
def lazy_import(name, as_=None):
# Doesn't handle error_msg well yet
import importlib
mod = importlib.import_module(name)
if as_ is not None:
name = as_
# yuck...
globals()[name] = mod
class NeedsNumpyFoo:
def __init__(self):
lazy_import("numpy", as_="np")
def foo(self):
return np.array([1,2,])
Я мог бы создать экземпляр модуля вне класса и указать на импортированный модуль, если импорт не завершится неудачей, но это то же самое, что и подход globals(). В качестве альтернативы lazy_import мог бы вернуть мод, и я мог бы вызывать его всякий раз, когда модуль необходим, но это равносильно простому импорту его повсюду, как и раньше.
Есть ли лучший способ справиться с этим?
Подробнее здесь:
https://stackoverflow.com/questions/705 ... -in-python