这就是为什么你永远不应该
import
与脚本运行的模块相同。最后得到两个完全独立的模块对象,
enum_test
和
__main__
,具有自己完全独立的全局命名空间,其中包含从同一代码构造的独立对象。
__main__.main()
生成一个dict,并用它填充
__main__.MyEnum
钥匙。
print_test_file.print_test
将该dict作为参数。但是它试图用
enum_test.MyEnum.A
. 而且这个钥匙不在口述里,所以你得到一个
KeyError
.
你的模块
也
具有循环依赖项,这被此问题掩盖。我敢肯定,在这种情况下,如果没有其他错误的话,您实际上可以摆脱循环依赖关系,但是必须仔细考虑顶级模块代码的执行顺序,这仍然令人困惑,因此最好避免它们。
一次解决这两个问题的简单方法是将共享代码移动到单独的共享模块中,脚本和测试模块都可以导入该模块。
# enum_test.py
from my_enum import MyEnum
import print_test_file
def main():
enumDict = dict()
enumDict[MyEnum.A] = 'abcd'
enumDict[MyEnum.B] = 'efgh'
print(enumDict[MyEnum.A])
print_test_file.print_test(enumDict)
if __name__ == "__main__":
main()
# print_test_file.py
import my_enum
def print_test(enumDict):
print(enumDict[my_enum.MyEnum.A])
# my_enum.py
from enum import Enum
class MyEnum(Enum):
A = 1
B = 2
现在,没有导入脚本的模块,也没有导入脚本的模块。(在技术术语中,您只需要一个树,脚本在根目录下,而不是一个包含循环的图。)
每隔几年,就有人建议更改python以消除这个问题,但实际上没有好的答案。它们可能会导致导入作为脚本运行的同一个模块出错,但这可能会破坏一些不常见但重要的用例(如
multiprocessing
)或者他们可以通过做一个隐式的
sys.modules['enum_test'] = sys.modules['__main__']
在某些情况下,实际上没有什么地方可以将代码中的循环依赖性(以及几乎所有其他关于这个问题的例子)从最无害的转为严重的bug。
(顺便说一句,我隐约记得,在一次讨论中,一位核心开发人员,也是一位老师,提到他的学生中很少有人会遇到这个问题,但是那些确实会接近班上最高水平的学生,所以至少你要有这种感觉。)