Python中循环导入方法的奇怪输出

时间:2013-01-06 15:44:38

标签: python oop dynamic module package

同一目录中有两个模块。

我正在使用Python 3.2

一个是a.py,就像这样:

import b
class orig:
    def test(self):
        print("hello")


o = orig()
o.test()

另一个是b.py,就像这样:

from a import orig
orig.test=lambda self: print("wrong")

当我运行这样的命令时:

python a.py

我希望在输出中只看到一个hello,但是,我在输出中看到两个hello。每个hello在一个单独的行中。

另外,我很困惑python如何处理彼此导入的两个模块的情况。

有没有人有这方面的想法?

3 个答案:

答案 0 :(得分:2)

直接运行python脚本时,就像使用python a.py一样,python解释器不会猜测该文件的模块路径应该是什么;它只是创建一个名为__main__的模块并运行它。

另一个细微之处在于,每次python遇到导入时, first 都会创建模块并将其存储在sys.modules中,以便同一模块的所有其他导入生成相同的模块对象。只有它离开了breadcrumb才会开始执行实现该模块的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使用了来自导入,这意味着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修改过的。

希望能够解决一些困惑。

答案 1 :(得分:0)

你输出两行是因为你执行两次a.py:一次作为主程序,一次导入b。避免循环导入,绝对不要导入你的主程序。

导入主程序的另一个副作用:你现在在这个程序中实际上有两个名为orig的类。

答案 2 :(得分:0)

仅次于@TokenMacGuy和@Ned:如果用以下内容替换a.py的结尾:

if __name__ == "__main__":
    o = orig()
    o.test()

你只会得到一个"你好"。

确实:避免循环依赖!