Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python中循环导入方法的奇怪输出_Python_Oop_Dynamic_Module_Package - Fatal编程技术网

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

Python中循环导入方法的奇怪输出,python,oop,dynamic,module,package,Python,Oop,Dynamic,Module,Package,同一目录中有两个模块 我正在使用Python 3.2 一个是a.py,如下所示: import b class orig: def test(self): print("hello") o = orig() o.test() from a import orig orig.test=lambda self: print("wrong") python a.py 另一个是像这样的b.py: import b class orig: def test(sel

同一目录中有两个模块

我正在使用Python 3.2

一个是a.py,如下所示:

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


o = orig()
o.test()
from a import orig
orig.test=lambda self: print("wrong")
python a.py
另一个是像这样的
b.py

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


o = orig()
o.test()
from a import orig
orig.test=lambda self: print("wrong")
python a.py
当我像这样运行命令时:

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


o = orig()
o.test()
from a import orig
orig.test=lambda self: print("wrong")
python a.py
我希望在输出中只看到一个
hello
,但是在输出中看到两个
hello
。每个
hello
在单独的行中

另外,我对python如何处理两个模块相互导入的情况感到困惑


有人对此有想法吗?

您将得到两行输出,因为您执行了两次a.py:一次作为主程序,一次在导入到b中时执行。避免循环导入,绝对不要导入主程序


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

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

另一个微妙之处是,每次python遇到导入时,它首先创建模块并将其存储在sys.modules中,以便同一模块的所有其他导入生成相同的模块对象。只有在剩下面包屑之后,它才会开始执行实现该模块的python代码

下面是发生的情况,您可以在shell控制台python上一步一步地键入
python a.py
创建一个
\uuuuuuuuuuuuuuuuuuuuuuuu主模块并开始计算该文件

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导入,这意味着
源代码现在需要存在,否则导入将失败

    ./b.py  b  2:  orig.test=lambda self: print("wrong")
b
monkey patches
a.orig
(注意:不是
\uuuu main\uuuu.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()
现在,
\uuuuuuu main\uuuuuuuu
正在定义一个类,实例化它并打印一些输出。还要注意,这是类
\uuuuuuu main\uuuuuuuuu.orig
的定义,而不是修改的
a.orig
b


希望这能消除一些困惑。

请支持@TokenMacGuy和@Ned:如果将a.py的结尾替换为:

if __name__ == "__main__":
    o = orig()
    o.test()
你只会得到一个“你好”


事实上:避免循环依赖!

通常应避免循环导入