【问题标题】:What is absolute import in python?python中的绝对导入是什么?
【发布时间】:2014-05-05 21:54:55
【问题描述】:

我是 Python 新手。我正在开发一个小项目。我需要从病房开始就遵循编码标准。如何正确使用import 语句。现在我正在研究 Python 2.7。如果我移至 3.x,与绝对导入有任何冲突吗?绝对导入和相对导入有什么区别?

【问题讨论】:

  • 你能澄清一下什么是绝对进口和相对进口吗?
  • @Ol'Reliable 它们在PEP 328 中有描述。

标签: python python-2.7 python-3.x


【解决方案1】:

这里绘制的absoluterelative 之间的区别与我们谈论绝对和相对文件路径甚至URL 的方式非常相似。

一个绝对的{import, path, URL}告诉你确切地如何得到你想要的东西,通常是通过指定每个部分:

import os, sys
from datetime import datetime
from my_package.module import some_function

Relative {imports, paths, URLs} 正是他们所说的:他们是 relative 到他们当前的位置。也就是说,如果目录结构发生变化或文件移动,这些可能会中断(因为它们不再意味着相同的东西)。

from .module_in_same_dir import some_function
from ..module_in_parent_dir import other_function

因此,要共享的代码首选绝对导入。


我在 cmets 中被要求提供一个示例,说明 from __future__ import absolute_import 如何与此联系,以及如何使用它。在尝试制定这个例子时,我意识到我也不能完全解释它的行为,所以我asked a new questionThis answer 提供了一个代码示例,显示了from __future__ import absolute_import 的正确工作实现,它实际上解决了歧义。

The accepted answer 更详细地说明了为什么它会以这种方式工作,包括对 Python 2.5 变更日志中令人困惑的措辞的讨论。本质上,该指令的范围(以及 Python 中绝对导入和相对导入之间的区别)非常非常狭窄。如果您发现自己需要这些区别来使您的代码正常工作,那么您最好尽可能重命名本地模块。

【讨论】:

  • 我也是这么想的。但如果是这样的话,为什么当我有from __future__ import (absolute_import) 时,后一种形式的导入仍然有效?
  • @raxacoricofallapatorius 假设您有一个名为 string 的本地模块。你打开一个解释器并发出import string。 Python 2.5 会给你本地模块。 Python 2.7+ 会给你string 库。该 future 指令将 Python 2.5 转换为 2.7 的默认行为。虚线形式是明确相对的,因此标准库不会有歧义。因此,它们总是以相同的方式工作。 More
  • 啊,我明白了,from __future__ absolute_import 禁止 隐式 相对导入(显式导入也可以)。对吗?
  • @raxacoricofallapatorius 我认为在该指令下,即使是隐式的也可以。它所做的只是让 Python 在发生冲突时更喜欢绝对版本——当导入语句可以被有效地解释为相对(本地模块)或绝对(标准库)时。换句话说,它通过在sys.path 上创建同名目录来防止您意外遮盖Python 标准库的某些部分,类似于命名变量list 遮盖内置list 函数的方式。跨度>
  • @raxacoricofallapatorius 我安装了 Python 2.5 来测试它并可能编写一个示例,结果我并不像我想象的那样清楚或确定发生了什么。我有 asked a new question 关于您可能有兴趣关注的这种特殊行为。
【解决方案2】:

导入通常应该在单独的行中:

是的:import os import sys

没有:import sys, os

尽管这样说是可以的:

from subprocess import Popen, PIPE 导入总是放在文件的顶部,就在任何模块 cmets 和文档字符串之后,模块全局变量和常量之前。

进口应按以下顺序分组:

  • 标准库导入。
  • 相关的第三方进口。
  • 本地应用程序/库特定导入。
  • 您应该在每组导入之间放置一个空行。

根据 Pep8:- 建议使用绝对导入,因为如果导入系统配置不正确(例如包内的目录结束时),它们通常更具可读性并且表现得更好(或至少提供更好的错误消息)在 sys.path 上):

import mypkg.sibling
from mypkg import sibling
from mypkg.sibling import example

但是,显式相对导入是绝对导入的可接受替代方案,尤其是在处理复杂的包布局时,使用绝对导入会不必要地冗长:

from . import sibling
from .sibling import example

标准库代码应避免复杂的包布局并始终使用绝对导入。

不应使用隐式相对导入,并且已在 Python 3 中删除。

从包含类的模块中导入类时,通常可以这样拼写:

from myclass import MyClass
from foo.bar.yourclass import YourClass

如果此拼写导致本地名称冲突,则明确拼写:

import myclass
import foo.bar.yourclass

并使用“myclass.MyClass”和“foo.bar.yourclass.YourClass”。

应避免使用通配符导入 (from <module> import *),因为它们会使命名空间中存在哪些名称变得不清楚,从而使读者和许多自动化工具感到困惑。通配符导入有一个可辩护的用例,即重新发布一个内部接口作为公共 API 的一部分(例如,用可选加速器模块中的定义覆盖接口的纯 Python 实现,以及哪些定义将被被覆盖是事先不知道的)。

https://www.python.org/dev/peps/pep-0008/#imports

【讨论】:

  • 为了避免长的绝对导入引用,也避免相对引用,我简单地使用了python函数定义,例如>>> mylog = parentdir.subdir.utils.logger.Logger; mylog.warning_log('oops')
猜你喜欢
  • 1970-01-01
  • 2018-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-06
相关资源
最近更新 更多