导入外部包的正确约定是什么?
What's the correct convention of importing external packages?
我想构建我自己的包,我在其中使用包 numpy
。对于更直观的示例,让我们考虑:
import numpy as np
def my_fun(x, y):
return np.linspace(x, y)
我的问题是:有没有更好的方法来包含外部包?我在包 numpy
的源代码中看到它们使用完全相同的约定,即在函数脚本中导入包。我们有更好的方法吗?
例如,让另一个 .py
文件只包含导入的包
根据 PEP 8 风格指南:
导入通常应该在不同的行上
# Correct:
import os
import sys
# Wrong:
import sys, os
虽然这样说也可以:
# Correct:
from subprocess import Popen, PIPE
导入总是放在文件的顶部
就在任何模块注释和文档字符串之后,模块全局变量和常量之前。
导入应按以下顺序分组:
- 标准库导入。
- 相关第三方进口。
- 本地 application/library 特定进口。
您应该在每组导入之间放置一个空行。
推荐绝对导入
如果导入系统配置不正确(例如当包内的目录在 sys.path 上结束时),它们通常更具可读性并且表现得更好(或至少给出更好的错误消息) :
import mypkg.sibling
from mypkg import sibling
from mypkg.sibling import example
但是,显式相对导入是绝对导入的可接受替代方案,尤其是在处理复杂的包布局时,在这种情况下使用绝对导入会不必要地冗长:
from . import sibling
from .sibling import example
标准库代码应避免复杂的包布局并始终使用绝对导入。
绝对不应使用隐式相对导入,并且已在 Python 3 中删除。
从包含 class 的模块导入 class 时。
通常这样拼写是可以的:
from myclass import MyClass
from foo.bar.yourclass import YourClass
如果此拼写导致本地名称冲突,请明确拼写:
import myclass
import foo.bar.yourclass
并使用“myclass.MyClass”和“foo.bar.yourclass.YourClass”。
应避免通配符导入(来自 import *)。
它们不清楚命名空间中存在哪些名称,混淆了读者和许多自动化工具。通配符导入有一个可靠的用例,即重新发布内部接口作为 public API 的一部分(例如,用 Python 覆盖接口的纯实现来自可选加速器模块的定义以及将被覆盖的确切定义事先并不知道。
以这种方式重新发布名称时,以下关于 public 和内部接口的准则仍然适用。
我想构建我自己的包,我在其中使用包 numpy
。对于更直观的示例,让我们考虑:
import numpy as np
def my_fun(x, y):
return np.linspace(x, y)
我的问题是:有没有更好的方法来包含外部包?我在包 numpy
的源代码中看到它们使用完全相同的约定,即在函数脚本中导入包。我们有更好的方法吗?
例如,让另一个 .py
文件只包含导入的包
根据 PEP 8 风格指南:
导入通常应该在不同的行上
# Correct:
import os
import sys
# Wrong:
import sys, os
虽然这样说也可以:
# Correct:
from subprocess import Popen, PIPE
导入总是放在文件的顶部
就在任何模块注释和文档字符串之后,模块全局变量和常量之前。
导入应按以下顺序分组:
- 标准库导入。
- 相关第三方进口。
- 本地 application/library 特定进口。
您应该在每组导入之间放置一个空行。
推荐绝对导入
如果导入系统配置不正确(例如当包内的目录在 sys.path 上结束时),它们通常更具可读性并且表现得更好(或至少给出更好的错误消息) :
import mypkg.sibling
from mypkg import sibling
from mypkg.sibling import example
但是,显式相对导入是绝对导入的可接受替代方案,尤其是在处理复杂的包布局时,在这种情况下使用绝对导入会不必要地冗长:
from . import sibling
from .sibling import example
标准库代码应避免复杂的包布局并始终使用绝对导入。
绝对不应使用隐式相对导入,并且已在 Python 3 中删除。
从包含 class 的模块导入 class 时。
通常这样拼写是可以的:
from myclass import MyClass
from foo.bar.yourclass import YourClass
如果此拼写导致本地名称冲突,请明确拼写:
import myclass
import foo.bar.yourclass
并使用“myclass.MyClass”和“foo.bar.yourclass.YourClass”。
应避免通配符导入(来自 import *)。
它们不清楚命名空间中存在哪些名称,混淆了读者和许多自动化工具。通配符导入有一个可靠的用例,即重新发布内部接口作为 public API 的一部分(例如,用 Python 覆盖接口的纯实现来自可选加速器模块的定义以及将被覆盖的确切定义事先并不知道。
以这种方式重新发布名称时,以下关于 public 和内部接口的准则仍然适用。