IPython 重新加载不同的模块?

IPython reloading different module?

我用我自己的 Python 内置字符串模块做了一个测试 名为 'string' 的模块,用于测试模块搜索路径行为。我的习惯 字符串脚本只有 print('string' * 2) 的内容。这是 位于当前目录中,如下面的代码所示。

Python 3.6.4 |Anaconda custom (64-bit)| (default, Jan 16 2018, 10:22:32) [MSC v.1900 64 bit (AMD64)]
Type 'copyright', 'credits' or 'license' for more information
IPython 6.2.1 -- An enhanced Interactive Python. Type '?' for help.

In [1]: %pwd
Out[1]: 'C:\Users\stephen'

In [2]: import string

In [3]: string
Out[3]: <module 'string' from 'C:\ProgramData\Anaconda3\lib\string.py'>

In [4]: import imp

In [5]: imp.reload(string)
stringstring
Out[5]: <module 'string' from 'C:\Users\stephen\string.py'>

关于IPython重新加载的三个问题:

  1. 为什么reload认为它实际导入的模块(本地string.py)已经被导入了?只是文件相同吗 姓名?
  2. 为什么重新加载导入的模块与已经导入的模块不同?它是否跳过了 sys.modules 字典的检查,这是 在原始导入过程中首先检查?
  3. 为什么reload/IPython/Python不知道它在这里拉了一个快的,换了一个模块?

编辑:在反复尝试处理 Stack Overflow 抱怨我的代码块的过程中,我无意中丢失了一些我想说的内容。这是我能记得的: IPython 在启动时将内置字符串模块添加到 sys.modules 字典中(sys.modules 在 sys.path 之前被搜索),这是常规 Python 交互式提示所不具备的不做。因此,与 IPython 相比,我从交互式提示中得到了不同的行为。使用交互式提示,我总是得到本地 string.py,因为 sys.path 从当前目录开始进行模块搜索。所以,我对常规交互 (Anaconda) 和 IPython 之间的区别的理解就这么多。我列出的问题仍然让我感到困惑。

Tested on my Kernel

看起来您使用的本地模块名称隐藏了应用程序所依赖的标准库或第三方包或模块的名称。 Python 导入通常从 sys.path 设置检查,该设置可能在 Users\stephen 下设置。因此,当我们重新加载它时,它会选择第一个出现的地方。希望对你有帮助。

供参考:https://python-notes.curiousefficiency.org/en/latest/python_concepts/import_traps.html

reload 应该 重复定位正在重新加载的模块的源代码的过程,如果它找到与原始导入找到的文件不同的文件, 应该 使用新文件。毕竟,它需要处理移动模块的情况,或者将普通模块更改为包或扩展模块的情况。

reload 而不是 应该查看 sys.modules 并在发现内容时停止。如果这样做,它将不执行重新加载!

reload 找到本地 string.py 文件而初始 IPython 内部导入没有找到的原因是因为导入路径自第一次导入以来已更改。您 运行 IPython 不会导致 Python 本身将工作目录放在模块搜索路径上,并且 IPython 导入了 string 模块来自该配置下的标准库。之后,IPython 将工作目录放在模块搜索路径本身,模仿常规交互 Python,因此 reload 找到了本地 string.py.