【问题标题】:Python import all from folderPython从文件夹中全部导入
【发布时间】:2021-11-28 12:24:30
【问题描述】:

我在处理我的 Django 项目时遇到了问题。 我在views.py 中有多个类。 它有 1200 行,所以我决定将这些视图移动到新文件夹中的单独文件中。 现在一个文件,例如 Customer.py 有 2 个用于不同操作的类。

这是我拆分views.py之前的项目结构:

MyProject
  core
    -  urls.py
  api
    -  views.py
  manage.py

拆分views.py后的项目结构

MyProject
  core
    -  urls.py
  api
    -  view
        -   *all the files with multiple classes in each file*
  manage.py

拆分views.py 后,我需要从core/urls.py 中视图文件夹内的所有文件中导入所有类。 我一直在尝试找出几个小时,现在可以弄清楚...

我目前的解决方案是在 urls.py 中做

from api.view import * 

同时在视图文件夹中有 init.py 正在做

from .oneOfManyFiles import *

适用于所有课程...

我非常不喜欢这个解决方案,我很想找到一些好看的简单优雅的解决方案。有人可以帮我吗?

非常感谢

【问题讨论】:

  • 第一次发现的时候觉得很简单很优雅....
  • “我非常不喜欢这个解决方案”为什么不?如果没有某种客观指标,我们通常不会在这里处理“优雅”。另请参阅meta.stackoverflow.com/questions/284236/…。提出适当的解决方案取决于为什么您有多个文件(太多而无法明确列出,或者是想要概括该过程的原因?)以及您想要的如何要命名和命名空间的结果。

标签: python python-3.x django python-import


【解决方案1】:

避免显式导入

你无法避免这种情况,至少在不破坏 IDE 上的代码完成的情况下是这样。

import importlib
import os

filedir = os.path.dirname(__file__)
modules = [f[:-3] for f in os.listdir(filedir) if os.path.isfile(os.path.join(filedir, f)) and f.endswith('.py') and f != '__init__.py']
for module_name in modules:
    module = importlib.import_module(f".{module_name}", package=__name__)
    names = [x for x in module.__dict__ if not x.startswith("_")]
    globals().update({name: getattr(module, name) for name in names})

我不会认为好看、简单或优雅。

自替换生成的导入

如果困扰您的是必须手动完成,那么您能做的最好的事情可能是编写一个脚本来生成导入语句并在运行时替换它自己。

import os

filedir = os.path.dirname(__file__)
modules = [f[:-3] for f in os.listdir(filedir) if os.path.isfile(os.path.join(filedir, f)) and f.endswith('.py') and f != '__init__.py']
imports = [f"    from .{module} import *\n" for module in sorted(modules)]

with open(__file__, 'r') as f:
    this_script = list(f)[:17]

with open(__file__, 'w') as f:
    f.write(f"""{''.join(this_script)[:-1]}
try:
{''.join(imports)[:-1] if imports else '    pass'}
except ImportError:
    pass
""")

try:
    from .oneOfManyFiles import *
except ImportError:
    pass

要完成代码,请运行项目或python -m api.view.__init__

【讨论】:

    猜你喜欢
    • 2018-08-19
    • 2013-02-19
    • 2020-04-26
    • 2019-08-21
    • 1970-01-01
    • 2013-08-26
    • 2018-07-19
    • 1970-01-01
    • 2019-06-13
    相关资源
    最近更新 更多