隐式相对导入在Python中如何工作?
假设我有以下文件隐式相对导入在Python中如何工作?,python,module,python-2.x,Python,Module,Python 2.x,假设我有以下文件 pkg/ pkg/__init__.py pkg/main.py # import string pkg/string.py # print("Package's string module imported") 现在,如果我运行main.py,它会显示“已导入包的字符串模块” 这是有道理的,并且按照以下内容中的陈述工作: “它将首先在包的目录中查找” 假设我稍微修改了文件结构(添加了一个核心目录): 现在,如果我运行pythoncore/main.py,它将加载内置的str
pkg/
pkg/__init__.py
pkg/main.py # import string
pkg/string.py # print("Package's string module imported")
现在,如果我运行main.py
,它会显示“已导入包的字符串模块”
这是有道理的,并且按照以下内容中的陈述工作:
“它将首先在包的目录中查找”
假设我稍微修改了文件结构(添加了一个核心目录):
现在,如果我运行pythoncore/main.py
,它将加载内置的string
模块
同样在第二种情况下,如果它必须遵守语句“它将首先查看包的目录”它是否应该加载本地字符串.py
,因为pkg
是“包目录”
我对术语“包目录”的理解是特别是的根文件夹,它是一个集合,其中包含\uu init\uuuuuuuuuuuuuuuupy
。因此,在本例中,pkg是“包目录”。它适用于main.py
以及子目录中的文件,如core/main.py
,因为它是这个“包”的一部分
这在技术上正确吗
PS:代码片段中
之后的内容是文件的实际内容(不带前导空格)。包是带有\uu init\uuuuupy.py
文件的目录,是的,在模块搜索路径上找到时作为模块加载。因此,pkg
只是一个包,如果父目录位于模块搜索路径上,则可以导入该包并将其视为一个包
但是通过以脚本形式运行pkg/core/main.py
文件,Python将pkg/core
目录添加到模块搜索路径,而不是pkg
的父目录。现在,在模块搜索路径上确实有一个\uuuu init\uuuuuuuuuy.py
文件,但这不是定义包的原因。您只有一个\uuuuuuuuuuuuuuuu主模块,与其他任何模块都没有包关系,并且您不能依赖隐式相对导入
您有三种选择:
不要将包内的文件作为脚本运行。将脚本文件放在包的外部,并根据需要导入包。您可以将它放在pkg
目录旁边,或者确保pkg
目录首先安装到模块搜索路径上已经存在的目录中,或者让脚本计算要添加到sys.path
的正确路径
使用可以像运行脚本一样运行模块。如果您使用python-mpkg.core
python将查找\uuuuu main\uuuuuu.py
文件并将其作为脚本运行。-m
开关会将当前工作目录添加到模块搜索路径中,因此当您在正确的工作目录中时,您可以使用该命令,一切都会正常工作。或者将软件包安装在模块搜索路径上已存在的目录中
让您的脚本将正确的目录添加到模块搜索路径中(基于os.path.absolute(\uu\u file\uu)
以获取当前文件的路径)。考虑到您的脚本始终命名为\uuuu main\uuu
,导入pkg.core.main
将添加第二个独立的模块对象;您将有两个独立的名称空间
我还强烈建议不要使用隐式相对导入。通过添加具有相同名称的嵌套包或模块,可以轻松屏蔽顶级模块和包<如果您试图在pkg
包中使用import time
,则会在标准库time
模块之前找到code>pkg/time.py
。相反,使用Python3模型的显式相对模块引用;将from\uuuuu future\uuuu import absolute\u import
添加到所有文件中,然后使用from。导入
以明确模块的导入位置。谢谢。我认为这涵盖了我的疑问以及我最初的问题,即运行模块中的脚本。但我应该澄清的一点是,通过“包目录”,我想到的是一组文件夹的根目录,其中包含\uuu init\uuuuuuuuupy
。原因是当我说zope
package时,我指的通常是根文件夹。看起来“package”这个词被重载了,表示不同的意思。可能您希望根据该假设编辑第一行:-@Nishant:zope
可能是包的根文件夹,但该文件夹本身不会添加到sys.path
模块搜索路径。您希望该文件夹的父目录位于模块搜索路径上。谢谢@Martijn Pieters,这是非常重要的一点。我不知道。@Nishant:但是,一个包可以有更多的嵌套包。因此,如果zope/foo
是一个包含zope/foo/\uuu init\uuuu.py
文件的目录,那么zope.foo
也可以是一个包。因此,包目录是任何包含\uuuu init\uuuu.py
文件的目录。
pkg/
pkg/__init__.py
plg/core/__init__.py
pkg/core/main.py # import string
pkg/string.py # print("Package's string module imported")