Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/299.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_Python Import_Circular Dependency - Fatal编程技术网

Python:从模块中循环导入成员

Python:从模块中循环导入成员,python,python-import,circular-dependency,Python,Python Import,Circular Dependency,假设我有以下代码 foo.py ------ import bar def abc(n): return bar.xyz(n-1) if n>0 else "abc" bar.py ------ import foo def xyz(n): return foo.abc(n-1) if n>0 else "xyz" 正如在这篇文章中所解释的,它将起作用。(简单的解释是,假设我们从python repl调用import foo,当第一次遇到import bar时,p

假设我有以下代码

foo.py
------
import bar
def abc(n):
    return bar.xyz(n-1) if n>0 else "abc"

bar.py
------
import foo
def xyz(n):
    return foo.abc(n-1) if n>0 else "xyz"
正如在这篇文章中所解释的,它将起作用。(简单的解释是,假设我们从python repl调用
import foo
,当第一次遇到
import bar
时,python将
bar
放入
sys.modules
并执行
bar.py
,当遇到
import foo
时,因为
foo
已经在
sys.modules
中,因此rt语句直接返回,即使
foo
模块不完整。)

现在,如果我将代码更改为以下内容:

foo.py
------
from bar import xyz
def abc(n):
    return xyz(n-1) if n>0 else "abc"

bar.py
------
from foo import abc
def xyz(n):
    return abc(n-1) if n>0 else "xyz"
导入将失败:

$ python foo.py
Traceback (most recent call last):
  File "foo.py", line 1, in <module>
    from bar import xyz
  File "/Users/yxiong/bar.py", line 1, in <module>
    from foo import abc
  File "/Users/yxiong/foo.py", line 1, in <module>
    from bar import xyz
ImportError: cannot import name xyz
$python foo.py
回溯(最近一次呼叫最后一次):
文件“foo.py”,第1行,在
从条形图导入xyz
文件“/Users/yxiong/bar.py”,第1行,在
从foo进口abc
文件“/Users/yxiong/foo.py”,第1行,在
从条形图导入xyz
导入错误:无法导入名称xyz
这里值得注意的是,python在从bar import xyz第二次尝试
时似乎失败了

  File "/Users/yxiong/bar.py", line 1, in <module>
    from foo import abc # so we attempt to import abc, but it depends on xyz

我的问题是,在这些步骤中到底发生了什么。具体地说,当python看到来自foo import abc的
语句时,它会做什么?

在这些框架中,首先python尝试加载/编译
foo
模块(称为
\uuu main\uuu
,只编译一次,但将执行两次):

但是
bar
尝试加载/编译
foo
并导入
abc
,我们在
sys.modules
中已经看到了。我们又回到了最初的进口:

  File "/Users/yxiong/foo.py", line 1, in <module>
    from bar import xyz 

让我们从Unix中的终端进行经验演示:

cat > foo.py
print('executing ' + __name__)
from bar import xyz
def abc(n):
    return xyz(n-1) if n>0 else "abc"
ctrl-d

ctrl-d

下一个实验:

cat > main.py
print('executing ' + __name__)
import foo
ctrl-d


还有一个有趣的问题。谢谢@Aaron。我做了另一个实验:从python repl运行
import foo
,这次它在
cannotimport name abc
(比从命令行运行
python foo.py
少一帧)失败。正如您所解释的,在命令行中运行时,
foo.py
首先作为
\uuuu main\uuuu
模块运行,这就是为什么python在
bar.py
遇到
foo
时再次尝试导入foo的原因,
foo
还不在
sys.modules
中。另一方面,如果从repl运行,
foo
sys.modules
中,因此python声称失败,而没有再次尝试导入它。编辑以澄清,因为我打算通知它只导入一次。实际上我不同意。如果我向这两个文件中添加
print\uuuuu file\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu;如果从repl运行,则仅打印两个
foo.py foo
bar.py bar
。这意味着当在命令行中运行时,
foo
确实被导入了两次,第一次作为
\uuuu main\uuuu
导入,第二次作为
foo
导入。如前所述,“执行脚本在名为
\uuu main\uuuu
的模块中运行,以自己的名称导入脚本将创建一个与
\uuu main\uu
无关的新模块。”
cat > foo.py
print('executing ' + __name__)
from bar import xyz
def abc(n):
    return xyz(n-1) if n>0 else "abc"
cat > bar.py
print('executing ' + __name__)
from foo import abc
def xyz(n):
    return abc(n-1) if n>0 else "xyz"
python foo.py
cat > main.py
print('executing ' + __name__)
import foo
python main.py