Python中关于模块导入的常见问题与解决方案

我在某个文件里需要用到 contract.serializers.contract_serializers 里的 PurchaseSerializer
那么我有两种写法:

import contract.serializers.contract_serializers
a = contract.serializers.contract_serializers.PurchaseSerializer(instance)

这一种层级太长了,写起来很不方便

from contract.serializers.contract_serializers import PurchaseSerializer
a = PurchaseSerializer(instance)

这一种写法看着很好
但是我有个疑问是:在[编写高质量代码:改善 Python 程序的 91 个建议](编写高质量代码:改善 Python 程序的 91 个建议)这本书里,提到了:要有节制的使用from ... import ...
而且如果两个文件有相互导入,使用from ... import ...大概率会报import error的错

那么应该怎么导入呢?


Python中关于模块导入的常见问题与解决方案

21 回复

为啥要相互导入。。

你见过哪个语言允许相互导入?


Python模块导入常见问题与解决方案

模块导入是Python开发的基础,但也是新手常踩坑的地方。下面我总结几个最常见的问题和直接可用的解决方案。

1. ModuleNotFoundError: No module named 'xxx’ 这是最经典的错误。原因就两个:要么没安装,要么路径不对。

# 解决方案:确保模块已安装且Python能找到
import sys
print(sys.path)  # 查看Python搜索路径

# 如果模块在自定义目录,手动添加路径
sys.path.append('/path/to/your/module')
import your_module

2. 相对导入在脚本中报错 在直接运行的脚本中使用相对导入会报ImportError

# 错误示例:直接运行 module.py
# from .submodule import something  # 会报错

# 解决方案1:改为绝对导入
from package.submodule import something

# 解决方案2:通过-m参数运行
# 命令行执行:python -m package.module

3. 循环导入问题 两个模块互相导入会导致AttributeError或奇怪的行为。

# 文件a.py
import b  # 同时b.py又import a

# 解决方案:重构代码结构
# 方法1:将公共代码移到第三个模块
# 方法2:在函数内部导入(延迟导入)
def some_function():
    import b  # 需要时才导入
    # 使用b模块

4. 导入同名模块冲突 当自定义模块与标准库或第三方库同名时,会优先导入路径中靠前的。

# 解决方案:重命名导入或调整路径顺序
import myjson as custom_json  # 给自定义模块起别名
from standard import json as std_json  # 给标准库起别名

5. init.py的作用 在Python 3.3+中,__init__.py不是必须的,但建议保留用于包初始化。

# __init__.py中可以定义包的公共接口
from .core import main_function
from .utils import helper

__all__ = ['main_function', 'helper']  # 控制from package import *的行为

6. 动态导入模块 有时需要根据条件导入不同的模块。

# 使用importlib实现动态导入
import importlib

module_name = "json"  # 可以是变量
module = importlib.import_module(module_name)
result = module.loads('{"key": "value"}')

总结建议:理解Python的模块搜索路径机制是关键。

好几个月没写 python 了,现在如果两个文件有相互导入 用 import 就不会报 import error 的错了????????????????

有种导入方法叫__important__(“contract.serializers.contract_serializers”).PurchaseSerializer 可以试一试 这种导入方法模块和函数全部要自己打比较麻烦 而且只能导入一次 我现在刚入门 在想这种导入方法跟 from important 之间的性能区别呢

import contract.serializers.contract_serializers as ooxx
a = ooxx.PurchaseSerializer(instance)

233 刚才查了下 还真可以,我还真是太无知了哈哈哈

相互导入是不对,但是实际情况的确会遇到

这样导入如果是相互导入的话也会报错,因为 as 会执行,然后就报错了

循环导入是要从代码结构上解决的问题哦。。

在函数或者类成员函数里面导入,是可以突破循环导入的限制的。

用 from xx import xx。
循环导入是另一个问题。

没错,但是我就要在顶部导入呢

如果实际情况出现,只能说明项目的设计有问题,换任何语言都有问题。

import as 了解一下

flask 相互导入的好像比较常见

用的地方再导入,就基本上不存在循环导入的问题。

你举个例子

import as

…刚好今天看 flask 讲到分文件导致的注册路由模块和主模块之间的循环导入,然后使用蓝本解决 23333

试试 import from as ????

回到顶部