Python中依靠import导入机制执行代码是否属于良好开发实践?
结论
你示例里的这种写法是完全合规的良好实践,属于Python里再常规不过的用法,根本不算奇技淫巧。
首先得说清楚Python import的原生逻辑:模块在整个程序进程生命周期里本来就只会被加载执行一次,第一次import的时候会把模块顶层代码从头到尾跑一遍,生成的模块对象会存在sys.modules缓存里,之后不管你在多少个文件里重复import这个模块,都不会重新执行代码,直接取缓存的对象就行,天然就满足你说的“配置只加载一次”的需求。
像示例里那样把固定配置项、常量定义在模块顶层,不管是Python标准库还是主流第三方项目,全是这么写的,用的时候直接import拿属性,简单清晰还不容易出错。
这些情况别这么写,容易踩坑
不是所有靠import触发执行的写法都是对的,只要你在模块顶层写下面这类代码,就属于坏实践:
- 带强副作用的重型操作:比如顶层直接发网络请求、连数据库、写本地文件、弹出交互窗口。你根本控制不了import的时机,万一其他无关代码误导入了这个模块,这些操作会莫名其妙触发,轻则拖慢启动速度,重则搞出循环导入、单元测试跑不通、生产环境误发请求的事故。
- 依赖运行时上下文的逻辑:比如顶层代码要读命令行参数、读程序启动后才会注入的环境变量,要是import发生在这些上下文准备好之前,直接就会抛错,排查起来还特别绕。
- 无保护的可变全局状态:如果顶层定义的是列表、字典这类可变对象,还允许各处随便改,因为模块是单例的,一处修改全进程生效,出了问题根本找不到是哪改坏的。
复杂初始化逻辑的更优写法
如果你说的“承载更复杂的逻辑”不是简单赋值,要读配置文件、做参数校验、甚至拉远程配置,别直接把逻辑全堆在模块顶层,可以选这两种更稳妥的方案:
- 惰性加载:把复杂逻辑封装成带缓存的函数,第一次调用的时候才真正执行,比如:
# mod.py from functools import lru_cache @lru_cache(maxsize=1) def get_config(): # 这里放读本地配置、校验参数、拉远程配置的复杂逻辑 return { "param1": "abc", "param2": "def" }
用的时候直接调用mod.get_config()拿配置就行,全程只会执行一次加载逻辑,还不会因为import提前触发不必要的操作。
- 显式初始化:如果必须要在程序启动阶段就把配置加载完,就单独写个
init_config()函数,在main.py最开头、所有业务逻辑跑之前手动调用。这种显式调用比隐式靠import触发逻辑清晰太多,排查问题的时候一眼就能看到配置初始化的位置。
要是只是像你示例里那样定义几个固定的配置常量,完全没必要搞上面这些复杂封装,直接写在模块顶层import用就行,是最地道的Python写法。
内容的提问来源于stack exchange,提问作者wojciech
相关产品推荐
相关产品推荐

