给出以下文件夹结构:
train
|__base
| |__model.py
| |__layer.py
|
|__nb
| |__model.py
| |__layer.py
|
|__norm
| |__model.py
| |__layer.py
nb和norm分别包含特定于nb和norm分布的模型和层。
这两个文件夹中的类Model
和Layer
是基本文件夹中各个类的子级。
假设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
一样?
答案 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