导入 Python 模块而不将其添加到本地名称空间

Import a Python module without adding it to the local namespace

我想做什么

我想导入一个 Python 模块而不将其添加到本地命名空间。

换句话说,我想这样做:

import foo
del foo

有更简洁的方法吗?

我为什么要这样做

简而言之,导入 foo 会产生我想要的副作用,但之后我真的不想在我的命名空间中使用它。

长版本是我有一个基 class,它使用 __init_subclass__() 来注册它的子 class。所以 base.py 看起来像这样:

class Base:
    _subclasses = {}

    def __init_subclass__(cls, **kwargs):
        super().__init_subclass__(**kwargs)
        cls._subclasses[cls.__name__] = cls

    @classmethod
    def get_subclass(cls, class_name):
        return cls._subclasses[class_name]

及其子class在单独的文件中定义,例如foo_a.py:

from base import Base

class FooA(Base):
    pass

等等。

这里的净效果是如果我这样做

from base import Base

print(f"Before import: {Base._subclasses}")

import foo_a
import foo_b

print(f"After import: {Base._subclasses}")

那我就看看

Before import: {}
After import: {'FooA': <class 'foo_a.FooA'>, 'FooB': <class 'foo_b.FooB'>}

所以我需要导入这些模块以增加对 Base._subclasses 的引用的副作用,但现在已经完成了,我的命名空间中不再需要它们,因为我将要使用 Base.get_subclass().

我知道我可以把它们留在那儿,但是这会进入 __init__.py 所以我想整理那个命名空间。

del 工作得很好,我只是想知道是否有更简洁或更惯用的方法来做到这一点。

如果要导入模块而不将模块对象分配给变量,可以使用 importlib.import_module 并忽略 return 值:

import importlib

importlib.import_module("foo")

请注意,使用 importlib.import_module 比直接使用 __import__ 内置函数更适合简单用法。有关详细信息,请参阅 builtin documenation