Python 循环导入的大坑(模拟 Flask 典型场景)

2016-12-03 16:38:14 +08:00
 guyskk

app.py

import pdb;pdb.set_trace()
app = 1
import model
#from model import User #ImportError: cannot import name 'User'
print(app)
print(model)
#print(model.User) #AttributeError: module 'model' has no attribute 'User'

model.py

import pdb;pdb.set_trace()
from app import app
User = app + 1

执行顺序

$ python app.py
> /tmp/demo/app.py(2)<module>()
-> app = 1
(Pdb) n
> /tmp/demo/app.py(3)<module>()
-> import model
(Pdb) n
> /tmp/demo/model.py(2)<module>()
-> from app import app
(Pdb) n
> /tmp/demo/app.py(2)<module>()
-> app = 1
(Pdb) n
> /tmp/demo/app.py(3)<module>()
-> import model
(Pdb) n
> /tmp/demo/app.py(4)<module>()
-> print(app)
(Pdb) n
1
> /tmp/demo/app.py(5)<module>()
-> print(model)
(Pdb) n
<module 'model' from '/tmp/demo/model.py'>
--Return--
> /tmp/demo/app.py(5)<module>()->None
-> print(model)
(Pdb) n
--Return--
> <frozen importlib._bootstrap>(222)_call_with_frames_removed()->None
(Pdb) c
1
<module 'model' from '/tmp/demo/model.py'>

回想自己学 Flask 的时候,也在这里被坑的好惨(前几天不长记性又被坑了一次)。
这里有个很严重的问题,你需要小心翼翼地理清导入顺序,而且就算程序跑起来了, 某些模块可能执行了两次,造成意想不到的结果。
解决方法是采用 Flask 最佳实践 https://zhuanlan.zhihu.com/p/22774028

但是呢,这是 Python 的缺陷还是 Flask 的缺陷?
我认为这是 Flask 的设计缺陷,@app.route看起来简单,全局对象用着一时爽, 但是非常容易产生循环依赖,一不小心就掉坑里了。

3472 次点击
所在节点    Python
0 条回复

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/325044

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX