python中同一模块的两个实例有问题?



我有两个模块如下:

模块 A - moda.py

import modb
x = None
def printx():
global x
print(x)
def main():
global x
x = 42
printx()
modb.printx()
printx()
if __name__ == '__main__':
main()

模块 B - modb.py

import moda
def printx():
moda.printx()
print('modb imported')

当我运行python moda.py时,我得到的输出是:

modb imported
42
None
42

我不明白为什么第二次打印(来自modb.printx(((是None。我认为python模块的行为就像单例一样。我错过了什么?

有人可以解释为什么modb中导入的模块与原始模块moda不同吗?

当遇到import语句时,解释器会在sys.modules中查找相应的键。如果找到密钥,它将绑定到您请求的名称。否则,将创建一个新的空模块对象放置在sys.modules中,然后填充。这样做的原因正是为了避免循环导入的无限循环。

运行模块时,将以名称__main__导入该模块。你卡

以下是将moda作为脚本运行时的事件顺序:

  1. moda.py的负载开始作为sys.modules['__main__']。此时,这只是一个空的命名空间
  2. import modbmoda.py遇到.为sys.modules['modb']创建新的空命名空间。
  3. import modamodb.py遇到.为sys.modules['moda']创建新的空命名空间。请注意,这与步骤 1 中的sys.modules['__main__']对象不同
  4. import modbmoda.py遇到.由于sys.modules['modb']存在,因此它绑定到该名称moda
  5. 由于moda.py当前正在以moda的名义加载,因此它完成了填充其命名空间而不运行导入保护。
  6. modb.py完成填充其命名空间(从步骤 2 开始(并运行print('modb loaded')
  7. moda.py中定义的__main__完成填充其命名空间(从步骤 1 开始(并运行导入保护。

希望这可以帮助您可视化发生的事情。您加载了三个模块,而不是两个模块,因为moda以两个不同的名称加载,并且作为两个完全不同的模块对象加载。

__main__中的导入防护调用__main__.main,执行以下操作:

  1. 设置__main__.x = 42(moda.x仍然None(
  2. __main__.printx打印__main__.x,这是42
  3. modb.printx调用moda.printx,它打印moda.x,这是None
  4. __main__.printx再次打印__main__.x,这仍然是42.

最新更新