python - 动态加载模块然后在加载的模块上使用 "from x import *"

标签 python django import

我有一些 django 应用程序,它们是按应用程序名称进行版本控制的。

appv1 appv2

应用程序中的 models.py 根据版本略有不同,但具有相同的模型名称。

我正在尝试将模型动态加载到当前命名空间中。 所以我做了一个函数来尝试获取模块并返回它:

def get_models_module(release):
    release_models_path = u"project.data_%s" % (release)
    _temp = __import__(release_models_path, globals(), locals(), ["models"], -1)
    models = _temp.models
    return models

然后我尝试从返回的模型模块加载所有模型,但它失败了。

models = get_models_module("1")
from models import *

发生这种情况时,我得到错误:

ImportError: No module named models

我检查过,返回的“models”对象被列为“module 'project.data_1.models' ...”, 但显然它不喜欢被重命名。

有没有一种方法可以从特定的应用程序版本加载所有定义的模型? 或者,有没有更好的方法来处理这种情况?

注意:目前仅在加载函数中将数据加载到数据库中,并没有通过任何 View 运行。


更新的解决方案:

感谢 Daniel Kluev 提供的解决方案,这是我更新后的函数:

def load_release_models(release):
    model_release = release.replace(u".", u"_").replace(u"-", u"d") 
    release_models_path = u"project.data_%s.models" % (model_release)
    # import all release models into (global) namespace
    exec(u"from {0} import *".format(release_models_path)) in globals()

注意 - 我正在加载全局变量,因为我需要访问整个文件中的这些模型。

最佳答案

from models import * 中,您没有引用 models 变量。您只是试图导入名为“models”的模块,显然该模块不存在。

您可以像这样使用 hack 将模块中的所有内容导入当前命名空间:

ldict = locals()
for k in models.__dict__:
    if not k.startswith('__') or not k.endswith('__'):
        ldict[k] = models.__dict__[k]

或者使用exec()加载模块,

exec("from project.data_{0}.models import *".format(release)) in locals()

关于python - 动态加载模块然后在加载的模块上使用 "from x import *",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3372361/

相关文章:

Django uwsgi 导入错误

python - 在 python (cv2) 中使用 OpenCV 增加彩色图像对比度的最快方法是什么?

django - 使用在模型之后加载的表单自定义 Wagtail 编辑界面

python - “makemigrations”要求使用非抽象模型继承的默认值

python - 如何将 Graphene GraphQL 框架与 Django REST 框架身份验证一起使用

python - 控制 python 导入以减少大小和开销

Python C API : T_INT was not declared in this scope

python - 如何获取 pygame 中鼠标点击位置的 RGB 值以及如何更改颜色? (Python 3.3.2)

python - asyncio.sleep 如何不阻塞线程?

javascript - jQuery - 在 jQuery.get 函数之后重新加载头脚本