【发布时间】:2014-11-20 04:02:07
【问题描述】:
主题是包导入和__init__ 文件:
规范中有一句话说
这些文件用于防止具有通用名称的目录 无意中隐藏了稍后出现在模块上的真实模块 搜索路径。如果没有这种保护措施,Python 可能会选择一个目录 这与您的代码无关,只是因为它看起来是嵌套的 在搜索路径上的较早目录中。
你能给我这方面的实际例子吗?
【问题讨论】:
标签: python python-3.x module directory
主题是包导入和__init__ 文件:
规范中有一句话说
这些文件用于防止具有通用名称的目录 无意中隐藏了稍后出现在模块上的真实模块 搜索路径。如果没有这种保护措施,Python 可能会选择一个目录 这与您的代码无关,只是因为它看起来是嵌套的 在搜索路径上的较早目录中。
你能给我这方面的实际例子吗?
【问题讨论】:
标签: python python-3.x module directory
如果您允许将 any 目录视为一个包,那么尝试导入一个同时作为目录存在的模块 和 作为搜索路径上的模块可能选择模块上的目录。
假设你有一个images 目录和一个images.py 模块。 import images 会找到 images 目录,如果它在搜索路径上找到的话。
通过要求__init__.py 来标记包,您可以在 Python 代码旁边包含此类数据目录,而不必担心掩盖具有相同名称的真正模块。
【讨论】:
当前Python documentation中没有这样的引用。
PEP 420 Implicit Namespace Packages (Python 3.3+) specifies:
<directory>/foo/__init__.py,则导入并返回常规包。<directory>/foo.{py,pyc,so,pyd},则导入并返回一个模块。扩展的确切列表因平台以及是否指定 -O 标志而异。此处的列表具有代表性。<directory>/foo 并且是一个目录,则记录它并继续扫描父路径中的下一个目录。即,如果<directory> 在sys.path 中,那么import foo 可能对应于<directory>/foo,即使没有<directory>/foo/__init__.py。 pep 被接受,因此与拥有命名空间包的好处相比,由于偶然的import foo 成功而可能造成混淆的风险被认为太小了。
除非您打算提供命名空间包,例如,为了让插件模块能够将它们放在不同的目录中(可作为不同的操作系统包安装),那么您应该始终为您的 Python 包提供__init__.py——显式优于隐含的。
【讨论】:
sys.path 中没有images/__init__.py 或images.{py,pyc,...} 那么images 目录可以导致import images 成功:"如果<directory> 是在sys.path 然后import foo 可能对应于<directory>/foo,即使没有<directory>/foo/__init__.py"