当前位置: 首页 > 面试题库 >

隐式相对导入在Python中如何工作?

鲁品
2023-03-14
问题内容

假设我有以下文件,

pkg/
pkg/__init__.py
pkg/main.py # import string
pkg/string.py # print("Package's string module imported")

现在,如果我跑步main.py,它说"Package's string module imported"

这是有道理的,并且按照此链接中的以下语句运行:

“它将首先在包的目录中查找”

假设我稍微修改了文件结构(添加了一个核心目录):

pkg/
pkg/__init__.py
plg/core/__init__.py
pkg/core/main.py # import string
pkg/string.py # print("Package's string module imported")

现在,如果我运行python core/main.py,它将加载内置string模块。

同样在第二种情况下,如果必须遵守“ 它将首先在软件包的目录中查找这样 的语句 ,是否
应该加载本地文件,string.py因为pkg它是“软件包的目录”?

我的术语“包目录”的意义是 明确根文件夹 一个的 集合 与文件夹__init__.py。因此,在这种情况下,
pkg 是“程序包目录”。它适用main.py于子目录,也适用于子目录中的文件,例如,core/main.py因为它是此“包”的一部分。

这在技术上正确吗?

PS:#代码段后面的内容是文件的实际内容(没有前导空格)。


问题答案:

软件包是带有__init__.py文件的目录,是的,并且 在模块搜索路径上找到时
作为模块加载。所以pkg只有一个包,你可以导入和处理作为一个整体 ,如果父目录是模块搜索路径上

但是通过将pkg/core/main.py文件作为 脚本
运行,Python将pkg/core目录添加到了模块搜索路径,而不是的父目录pkg__init__.py现在,您的模块搜索路径上确实有一个文件,但这不是定义包的原因。您只有一个__main__模块,没有其他任何包关系,并且您不能依赖隐式相对导入。

您有三种选择:

  1. 不要将包中的文件作为脚本运行。将脚本文件 放在之外 ,并根据需要导入脚本。你可以把它 旁边pkg目录,或者确保pkg目录首次安装到一个目录已经是模块搜索路径,或让你的脚本计算添加到正确的道路sys.path

  2. 使用-m命令行开关可以像运行脚本一样运行模块。如果您使用python -m pkg.corePython,则会查找__main__.py文件并将其作为脚本运行。该-m交换机将增加当前工作目录到你的模块搜索路径,所以你可以使用这个命令时,你在正确的工作目录,这样就可以了。或者将软件包安装在模块搜索路径上已经存在的目录中。

  3. 让您的脚本将正确的目录添加到模块搜索路径(基于os.path.absolute(__file__)以获取当前文件的路径)。考虑到您的脚本 始终 被命名为__main__,并且导入pkg.core.main将添加另一个独立的模块对象;您将拥有两个单独的命名空间。

我也 强烈
建议不要使用隐式相对导入。您可以通过添加嵌套的软件包或具有相同名称的模块来轻松地屏蔽顶级模块和软件包。如果您尝试在包内使用,将pkg/time.py在standard-
librarytime模块之前找到。相反,请使用 显式 相对模块引用的Python
3模型;添加到您的所有文件,然后用于明确指出从何处导入模块。import time``pkg __from __future__ import absolute_import``from . import <name>



 类似资料:
  • 在PEP 8中--Python代码风格指南 明确的相对进口是绝对进口的一种可接受的替代方案 有人能详细解释一下吗?

  • 问题内容: 想象一下这个目录结构: 我正在编码,我需要从中导入一些东西。我该怎么办? 我尝试过,但是得到了“未打包的相对导入尝试”。 我四处搜寻,但只发现骇客。有没有一种干净的方法? 问题答案: 每个人似乎都想告诉你应该做什么,而不仅仅是回答问题。 问题是你通过将作为参数传递给解释器而将模块作为运行。 从PEP 328: 相对导入使用模块的属性来确定该模块在包层次结构中的位置。如果模块的名称不包含

  • 问题内容: 想要导入 这只是一个示例,但实际上我只想在父目录中进行模块的相对导入。我已经尝试了各种方法并得到此错误… 我在某处读到该程序开始处的脚本不应该放在程序包中,并且我尝试像这样修改结构… 但有同样的错误。 我该怎么做?这是否足够? 编辑:在Python 2 问题答案: 稍微摆弄一下之后,我意识到了如何设置它,并且出于特定性考虑,我将不使用foo bar名称。我的项目目录设置为… 一条线看起

  • 问题内容: 大家好-我正在用Python中的相关知识来表达自己的观点。我已经阅读了30篇文档,并在SO和其他论坛上阅读了很多帖子-似乎还是行不通。 我的目录结构目前看起来像这样 我希望expander.py和language_id.py可以访问功能模块。我运行python main.py,可以从components.expander import 和components.language_id i

  • 这在python 3中有效,但在python 2(版本2.7)中会发出一个ImportError: Shell命令: mymodule/__init__.py MyModule/X.py MyModule/y.py 但这只适用于Python3,而不适用于Python2(因为相同的ImportError)。 在Python2中使其工作的唯一方法是使用具有以下不推荐符号的相对导入: 我真的不喜欢它,因

  • 问题内容: 我想从同一目录中的另一个文件导入函数。 有时它对我有用,但有时我得到: 有时它可与一起使用,但有时我也会得到: 我不了解这里的逻辑,也找不到任何解释。这看起来完全是随机的。 有人可以向我解释所有这些背后的逻辑是什么? 问题答案: 不幸的是,该模块需要位于程序包内部,有时还需要作为脚本运行。知道如何实现吗? 像这样的布局很普遍… … mymodule.py像这样… ......一个myo