给出以下包结构:
master.py
models/
__init__.py
model1.py
model2.py
model3.py
其中每个模型* .py文件包含一个或多个类,如何在master.py中创建一个动态导入其中每个类并将其设置为自身属性的类?目前我有以下内容:
class DB:
def __init__(self):
from models.model1 import foo, bar
from models.model2 import foo2
from models.model3 import bar2
self.foo = foo
self.bar = bar
self.foo2 = foo2
self.bar2 = bar2
但这要求我明确说明每个导入的模块和类。我希望这个过程是自动/软编码的,所以如果我以后添加或删除模型,我将不需要更新数据库类。
答案 0 :(得分:0)
嗯......我不认为这是最好的方式 - 我个人更喜欢手动处理所有导入。但我会假设你有理由并回答你的问题。
首先,您需要models
作为模块,因此在继续之前添加文件models/__init__.py
。
import inspect
import os
import sys
class DB(object):
def __init__(self):
# Get current file (`master.py`)'s directory and the `models` directory.
selfdir = os.path.dirname(os.path.abspath(__file__))
models_dir = os.path.join(selfdir, 'models')
# Get all files in `models` that are Python files.
models_files = [file for file in os.listdir(models_dir) if os.path.isfile(os.path.join(models_dir, file)) and file.endswith('.py')]
model_names = [model[:-3] for model in models_files]
for model_name in model_names:
# Exploit Python's ability to execute arbitrary code.
module_name = 'models.{name}'.format(name=model_name)
exec("import {module}".format(module=module_name))
module = sys.modules[module_name]
classes = inspect.getmembers(module, inspect.isclass)
for module_class in classes:
setattr(self, module_class[0], module_class[1])
我测试了它(在2.7.11中)并且效果很好,所以如果有什么东西不适合你,请告诉我。这里有一些假设,你只需要在你的代码库中保证,可能是通过文档。我没有处理我可能应该使用models
目录的IO异常,但你可以添加我认为。此外,有人可能会制作一个聪明的文件名并强制执行任意代码。所以......小心点。