当您直接运行python 脚本时,就像您对python a.py 所做的那样,python 解释器不会猜测该文件的模块路径应该是什么;它只是创建了一个名为 __main__ 的模块并运行它。
另一个微妙之处是每次python遇到导入时,它首先创建模块并将其存储在sys.modules中,以便同一模块的所有其他导入产生相同的模块对象。只有留下面包屑后,它才会开始执行实现该模块的 python 代码。
这就是发生的事情,一步一步,你在你的 shell 控制台上输入python a.py,python
创建一个__main__ 模块并开始评估该文件。
the file being parsed
|
| the module being imported
| |
./a.py __main__ 1: import b
好的,所以首先发生的是a.py 导入了一些东西。它以前从未导入过,所以它搜索路径并找到b.py;由于我们仍在尝试导入另一个文件,因此我将缩进一点以显示这一点。
./b.py b 1: from a import orig
在b.py 中发生的第一件事是它尝试导入a。但a 也从未被导入;当python搜索路径时,它会找到a.py
./a.py a 1: import b
看起来很眼熟;但是 b 已经被导入了;这个b 将是同一个(仍在导入过程中!
./a.py a 2: class orig:
./a.py a 3: def test(self):
./a.py a 4: print("hello")
./a.py a 5:
./a.py a 6:
./a.py a 7: o = orig()
./a.py a 8: o.a()
好的。一个类被创建,实例化,并出现一些输出; a 现已完成导入;很好,因为 b 使用了 from 导入,这意味着 orig 现在需要存在,否则导入会失败。
./b.py b 2: orig.test=lambda self: print("wrong")
b猴子补丁a.orig(注意;不是__main__.orig)。 b 现在也导入完成了。
./a.py __main__ 2: class orig:
./a.py __main__ 3: def test(self):
./a.py __main__ 4: print("hello")
./a.py __main__ 5:
./a.py __main__ 6:
./a.py __main__ 7: o = orig()
./a.py __main__ 8: o.a()
现在__main__ 正在定义一个类,实例化它并打印一些输出。另请注意,这是__main__.orig 类的定义,而不是修改后的a.orig b。
希望这能消除一些困惑。