从基类的构造函数中的同一子模块导入其他子类

时间:2020-05-05 14:59:23

标签: python python-import

给出以下文件夹结构:

train
|__base
|  |__model.py
|  |__layer.py
|
|__nb
|  |__model.py
|  |__layer.py
|
|__norm
|  |__model.py
|  |__layer.py

nb和norm分别包含特定于nb和norm分布的模型和层。 这两个文件夹中的类ModelLayer是基本文件夹中各个类的子级。 假设Model的一个实例包含Layer的一个实例,并且model.layer当然必须来自同一文件夹。 但是我需要从base.model.py调用模型的超级构造函数,并在其中创建特定于分发的层。

我可以做某事。在基本模型构造函数中是这样的:

__init__(self, distribution, **kwargs):
    if distribution == 'nb':
        from nb.layer import Layer
    elif distribution == 'norm':
        from norm.layer import Layer
    else:
        assert False, "Unrecognized distribution."
    self.layer = Layer()

现在,我需要了解基本模型中的所有发行版,并对通过的发行版字符串进行硬编码。但是我的工具需要可扩展,因此我不知道将来会添加哪些其他发行版。我想找到一个理想的解决方案,使其能够根据调用了基础模型构造函数的子模型自动检测必须从哪个子文件夹导入(即,如果创建了范本模型,则基础模型还应该导入norm层,而不是nb层。

有什么办法可以解决吗? 完美的解决方案无需将distribution之类的任何其他参数传递给基本构造函数即可使用。 但是,即使有必要通过distribution,也有可能以某种方式将正确的路径传递到nb / norm子文件夹并执行某项操作。像from <distribution>.layer import Layer一样?

1 个答案:

答案 0 :(得分:0)

一种实现方法是使用importlib.import_module

from importlib import import_module


class Model:
    __init__(self, distribution_module: str):
        layers = import_module(name='...' + distribution_module + '.layers', package=__name__)
        self.layer = layers.Layer()

distribution_module必须以子模块命名(在这种情况下,即'norm'或'nb')。根据文件夹的结构,相对于package的相对路径必须附加点(即,在这种情况下为'...',因为__name__是'train.base.model')。 如果提供绝对路径,也可以丢弃package参数。

请参阅文档:https://docs.python.org/3/library/importlib.html#importlib.import_module