Pra*_*eri 11 python python-import
我正在使用Flask 蓝图功能创建模块化应用程序.结果,我的目录结构是这样的:
project
__init__.py
config.py
mould.py
modules
__init__.py
core
__init__.py
core.py
db.py
models.py
Run Code Online (Sandbox Code Playgroud)
这里的modules目录不会与Python模块混淆,它们用于为我的项目提供模块化结构(核心模块,foo模块,条形模块等).现在,模块目录中的每个文件夹(以及其中包含相同名称的模块core.core)都可以通过以下方式动态导入到我的主烧瓶app(mould.py)中:
for item in os.listdir("modules"):
if not os.path.isfile("modules" + os.sep + item) and not item.startswith("__"):
ppath = "modules" + "." + item
fullpath = "modules" + "." + item + "." + item
module = importlib.import_module(fullpath)
app.register_blueprint(module.app)
print("Registered: " + ppath)
Run Code Online (Sandbox Code Playgroud)
因此,我无法在模块脚本中执行此操作,例如db.py:
import models
Run Code Online (Sandbox Code Playgroud)
因为它在项目级别执行整个模块时会产生路径错误,所以我必须这样做:
from . import models
Run Code Online (Sandbox Code Playgroud)
这解决了这个问题,我能够成功导入所有模块.但是,当我进入核心模块目录进行一些故障排除并启动python解释器时,它不允许我导入db模块:
>>> import db
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "db.py", line 7, in <module>
from . import models
ImportError: attempted relative import with no known parent package
Run Code Online (Sandbox Code Playgroud)
有没有解决的办法?那么,我可以在代码和解释器中成功导入db模块吗?
我知道我参加聚会迟到了,但我想我已经找到了解决这个问题的方法。希望这对从事大型 Python 项目的其他人有用。
诀窍是尝试一种导入格式,如果第一种格式失败,则退回到另一种格式。
数据库.py
try:
# Assume we're a sub-module in a package.
from . import models
except ImportError:
# Apparently no higher-level package has been imported, fall back to a local import.
import models
Run Code Online (Sandbox Code Playgroud)
从好的方面来说,这种方法非常简单,但扩展性不佳(模块名称重复)。可以通过以编程方式导入来改进扩展。
数据库.py
import importlib
root = 'project.modules.core'
my_modules = ['core', 'models']
for m in my_modules
try:
globals()[m] = importlib.import_module(root + '.' + m)
except ImportError:
globals()[m] = importlib.import_module(m)
Run Code Online (Sandbox Code Playgroud)
globals()是全局符号表。
当然,现在需要在每个模块中复制此功能。我不确定这实际上是对第一种方法的改进。但是,您可以将此逻辑分离到其自己的独立包中,该包位于pythonpath上的某个位置。
package_importer.py
import importlib
def import_module(global_vars, root, modules):
for m in modules
try:
global_vars[m] = importlib.import_module(root + '.' + m)
except ImportError:
global_vars[m] = importlib.import_module(m)
Run Code Online (Sandbox Code Playgroud)
数据库.py
import package_importer
root = 'project.modules.core'
my_modules = ['core', 'models']
package_importer.import_module(globals(), root, my_modules)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6028 次 |
| 最近记录: |