谁能解释一下同一 Python 模块的两次导入何时会导致两个不同的模块对象?

Can anyone explain when two imports of the same Python module can result in two different module objects?

提问人:Throw Away Account 提问时间:11/11/2023 更新时间:11/11/2023 访问量:25

问:

去年,我在 Python 3.7.2 中编写了以下三个模块:

# my_module.py
my_counter = 0                                                                                                                                                                                               

def increment_counter():                                                                                                                                                                                     
  global my_counter                                                                                                                                                                                          
  my_counter += 1                                                                                                                                                                                            
# client_module1.py                                                                                                                                                                                          

import my_module                                                                                                                                                                                             

def increment_counter():                                                                                                                                                                                     
  my_module.increment_counter()                                                                                                                                                                              
  print('Counter from client 1 is: %d' % my_module.my_counter                                                                                                                                                
# client_module2.py                                                                                                                                                                                          

import my_module                                                                                                                                                                                             

def increment_counter():                                                                                                                                                                                     
  my_module.increment_counter()                                                                                                                                                                              
  print('Counter from client 2 is: %d' % my_module.my_counter                                                                                                                                                

然后,我在 IPython 中尝试了以下操作:

     In [1]: import client_module1                                                                                                                                                                                
                                                                                                                                                                                                                  
     In [2]: import client_module2                                                                                                                                                                                
                                                                                                                                                                                                                  
     In [3]: client_module1.increment_counter()                                                                                                                                                                   
     Counter from client 1 is 1                                                                                                                                                                                   
                                                                                                                                                                                                                  
     In [4]: client_module2.increment_counter()                                                                                                                                                                   
     Counter from client 2 is 1                                                                                                                                                                                   
                                                                                                                                                                                                                  
     In [5]: client_module1.my_module is client_module2.my_module                                                                                                                                                 
     Out [5]: False                                                                                                                                                                                               

我以为这只是 Python 的不幸工作方式。

今天,在阅读了声称上述结果不是发生的事情的文档后,我再次尝试了这个实验。但我得到了不同的结果:

     In [1]: import client_module1                                                                                                                                                                                
                                                                                                                                                                                                                  
     In [2]: import client_module2                                                                                                                                                                                
                                                                                                                                                                                                                  
     In [3]: client_module1.increment_counter()                                                                                                                                                                   
     Counter from client 1 is 1                                                                                                                                                                                   
                                                                                                                                                                                                                  
     In [4]: client_module2.increment_counter()                                                                                                                                                                   
     Counter from client 2 is 2                                                                                                                                                                                   
                                                                                                                                                                                                                  
     In [5]: client_module1.my_module is client_module2.my_module                                                                                                                                                 
     Out [5]: True                                                                                                                                                                                               

显然,第二个结果是 Python 模块的行为方式。文档声称,当通过不同的显式路径(例如直接通过 PYTHONPATH,然后间接通过同样位于 PYTHONPATH 上的包含目录)或通过不同的方法(例如在一个地方但在其他地方)导入同一模块时,会发生唯一的例外情况。import my_modulefrom somewhere import my_module

但事实并非如此。当我在两个实验中启动 IPython 时,这些文件都在当前工作目录中,并且 import 语句与上面显示的完全相同。未设置 PYTHONPATH,并且目录中没有额外的文件。

有谁知道哪种 Python 导入边缘情况有时会导致这种情况发生,但其他情况下则不然?为了能够可靠地执行某些涉及全局状态的事情,了解这一点非常重要。

在这两个实验中,我都使用了 Python 3.7.2 和 IPython 7.33.0。

蟒蛇 python-import

评论

2赞 user2357112 11/11/2023
我们只能告诉你,你已经忘记了(或从未注意到)你之前情况的一些重要细节。也许你搞砸了 or .也许你有一个错别字。我们不能仅仅根据你无法重现的行为的模糊记忆来告诉你去年发生了什么。sys.pathsys.modules
0赞 Throw Away Account 11/14/2023
我仔细记录了我的行为和我为获得它而采取的步骤。这里没有列出任何带有 or 的代码,因此我没有搞砸 or 。sys.pathsys.modulessys.pathsys.modules

答: 暂无答案