同步阅读进度,多语言翻译,过滤屏幕蓝光,评论分享,更多完整功能,更好读书体验,试试 阅读 ‧ 电子书库
Recursive from Imports May Not Work
I saved the most bizarre (and, thankfully, obscure) gotcha for last. Because imports execute a file’s statements from top to bottom, you need to be careful when using modules that import each other (known as recursive imports). Because the statements in a module may not all have been run when it imports another module, some of its names may not yet exist.
If you use import to fetch the module as a whole, this may or may not matter; the module’s names won’t be accessed until you later use qualification to fetch their values. But if you use from to fetch specific names, you must bear in mind that you will only have access to names in that module that have already been assigned.
For instance, take the following modules, recur1 and recur2. recur1 assigns a name X, and then imports recur2 before assigning the name Y. At this point, recur2 can fetch recur1 as a whole with an import (it already exists in Python’s internal modules table), but if it uses from, it will be able to see only the name X; the name Y, which is assigned below the import in recur1, doesn’t yet exist, so you get an error:
# recur1.py
X = 1
import recur2 # Run recur2 now if it doesn't exist
Y = 2
# recur2.py
from recur1 import X # OK: "X" already assigned
from recur1 import Y # Error: "Y" not yet assigned
C:\misc> C:\Python30\python
>>> import recur1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "recur1.py", line 2, in <module>
import recur2
File "recur2.py", line 2, in <module>
from recur1 import Y
ImportError: cannot import name Y
Python avoids rerunning recur1’s statements when they are imported recursively from recur2 (otherwise the imports would send the script into an infinite loop), but recur1’s namespace is incomplete when it’s imported by recur2.
The solution? Don’t use from in recursive imports (no, really!). Python won’t get stuck in a cycle if you do, but your programs will once again be dependent on the order of the statements in the modules.
There are two ways out of this gotcha:
请支持我们,让我们可以支付服务器费用。
使用微信支付打赏
