Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/295.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,两个文件,file1.py,file2.py。有人能解释为什么第1.8行会打印spam==1而不是spam==2吗?我已经阅读了所有python循环导入文章,但我仍然不理解这一点。另外,我不明白为什么从file2导入时会从头开始解释file1。我的印象是,一旦模块导入一次,它们就不会再次加载 # file1.py print('1.1: initializing spam to 0') spam = 0 spam += 1 print('1.4: spam == {}'.format(spam)

两个文件,file1.py,file2.py。有人能解释为什么第1.8行会打印spam==1而不是spam==2吗?我已经阅读了所有python循环导入文章,但我仍然不理解这一点。另外,我不明白为什么从file2导入时会从头开始解释file1。我的印象是,一旦模块导入一次,它们就不会再次加载

# file1.py
print('1.1: initializing spam to 0')
spam = 0
spam += 1
print('1.4: spam == {}'.format(spam))
print('1.5: importing file2')
import file2
print('1.7: imported file2')
print('1.8: spam == {}'.format(spam))  # why 1 and not 2?
print('FILE 1 PARSED')  # why is this executed twice?

# file2.py
print('\t\t\t2.1: importing file1')
import file1
print('\t\t\t2.3: imported file1, file1.spam == {}'.format(file1.spam))
file1.spam += 1
import file1
print('\t\t\t2.6: print from file2: file1.spam == {}'.format(file1.spam))
print('\t\t\tFILE 2 PARSED')
我得到的结果是:

1.1: initializing spam to 0
1.4: spam == 1
1.5: importing file2
            2.1: importing file1
1.1: initializing spam to 0
1.4: spam == 1
1.5: importing file2
1.7: imported file2
1.8: spam == 1
FILE 1 PARSED
            2.3: imported file1, file1.spam == 1
            2.6: print from file2: file1.spam == 2
            FILE 2 PARSED
1.7: imported file2
1.8: spam == 1
FILE 1 PARSED

我理解避免循环进口,但我需要理解其逻辑

file1.py
作为主脚本运行时,它不是
file1
模块。它是
\uuuuuuuuuuuuu主模块。假设它是一个完全独立的文件,恰好与
file1
模块完全相同,因为Python就是这样处理它的

Python运行
file1.py
作为
\uuuu main\uuuu
,导入
file2
,导入
file1
。由于
\uuuu main\uuuu
模块与
file1
模块不同,因此
file1.py
会再次运行

file1
导入
file2
时,由于已导入
file2
file1
获取半构造的
file2
模块对象并继续。它没有给
file2
增加
file1.spam的机会。这就是为什么第1.8行的第一个实例打印1


当执行返回到
file2
时,它会增加
file1.spam
,因此第2.6行打印2。但是,
\uuuuuu main\uuuuu.spam
仍然是1。这就是为什么当执行返回到
\uuuu main\uuuu
时,第1.8行的第二个实例也会打印1

  • 看看是否已经有一个具有该名称的模块,如果是,请立即返回它
  • 模块尚未导入,因此创建模块对象并立即将其放入注册表,然后加载源代码并执行它
  • 如果执行
    file1
    会发生什么情况?执行将作为主程序启动,然后

  • file1
    code导入
    file2
    :由于它不存在,因此创建模块对象并开始执行
    file2
  • file2
    code导入
    file1
    :由于
    file1
    没有作为模块出现,因此创建了一个模块对象,并开始执行
    file1
    (作为模块!)
  • file1
    code(作为模块)导入
    file2
    :模块已经存在,因此立即返回部分构造的
    file2
    模块对象
  • file1
    模块完成执行,导入后继续执行
    file2
  • file2
    模块完成执行,导入后主程序恢复时,
    file1
  • 程序完成
  • 换句话说,
    垃圾邮件将有两个实例:一个在“主程序”文件1.py中,另一个在模块
    文件1

    考虑这个简化的测试用例:

    # p1.py
    import p2, sys
    p1d = {}
    print id(p1d), id(sys.modules['p1'].p1d)
    
    # p2.py
    import p1
    print "HERE"
    
    运行
    p1.py
    您将得到如下输出

    18465168 18465168
    HERE
    17940640 18465168
    
    前两个数字相等,因为打印是从
    p1
    模块执行的,而后两个数字不同,因为打印是从属于不同实例的
    p1
    主程序执行的


    PS:如果你有意编写这样做的代码(例如,一个main作为一个模块间接导入另一个自身实例),你应该被关进监狱:-)

    请看--我认为那里有足够的信息来回答你的问题。你是对的,它确实回答了这个问题,但是@6502的答案直接印在了我的脑海里,而另一篇文章的情况却不是这样:)答案很好,现在完全明白了!非常感谢!