【问题标题】:Bizarre Python Import Issue - Relative Imports of Builtins? [duplicate]奇怪的 Python 导入问题 - 内置函数的相对导入? [复制]
【发布时间】:2013-05-10 08:16:40
【问题描述】:

Python 2.7 做了一些非常奇特的事情,当您在后台查看它以在包中导入时。基本上,由于我真的无法理解的原因,它存储了内置插件的相对导入(除其他外)。最小用例如下。

假设目录结构为:

\BaseFolder
   * __init__.py
   * MainFile.py
   \TestFolder
       * __init__.py
       * TestModule.py

两个 __init__.py 都是空的。 MainFile.py 只说:

import TestFolder.TestModule
import sys
for x in sorted(sys.modules.keys()):
    print x

TestModule.py 说:

import os

使用 Python 运行 MainFile.py 会为您提供导入模块的列表。当您查看模块的键时,会发现一堆垃圾,但您可以找到以下键:

TestFolder
TestFolder.TestModule
TestFolder.os
...
os

如果您查看这些模块的值,TestFolder.os 为无。但为什么它首先存在呢?为什么模块列表会注册一个在查找时已被证明不存在的模块?我假设发生这种情况是因为系统首先在 TestFolder 中检查“os”库(因此是 TestFolder.os),然后在内置程序中查找。为什么仅仅因为你检查了就添加一个条目?有谁知道为什么 Python 会这样做?也许只是因为它不再检查这些位置的库?

【问题讨论】:

  • 这是一个标记,表明相关模块TestFolder.os 不存在。这使得未来的进口更快。这是一个愚蠢的问题,我很快就会找到原件。
  • 我同意这看起来像是虚拟模块问题的重复症状,现在已经说明了。投票结束。

标签: python import


【解决方案1】:

缓存包括未命中和命中。 TestFolder.os==None 只是意味着 python 寻找一个名为“os”的包相关模块,没有找到它,然后继续进行下去。它缓存包的绝对名称“TestFolder.os”,因为其他模块会这样称呼它。它将值设置为 None 以便其他模块的导入不必再次检查文件系统。

【讨论】:

  • 这就是我的想法。我的问题的根源是误解 sys.modules 是模块的实际列表,而不是记录命中和未命中结果的缓存。
  • 然而,公平地说,相关的 Python 文档是可怕的:“这是一个将模块名称映射到已经加载的模块的字典”(docs.python.org/2/library/sys.html)。如果他们可以将其称为系统尝试加载的模块缓存(使用其正常的解析顺序),他们可以避免一些令人头疼的问题。
  • @Namey - 是的,实验和被边缘条件绊倒都是 python 游戏的一部分!
猜你喜欢
  • 2013-03-02
  • 1970-01-01
  • 2021-04-05
  • 1970-01-01
  • 2011-09-01
  • 2014-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多