繁体   English   中英

在python中导入外部模块的最佳实践

[英]Best practice for importing external module in python

让我通过一个简化的例子来问这个问题。 假设我在一个目录中有一个名为 example.py 的 python2 脚本,其中包含我编写的另一个名为 utils.py 的脚本。 在example.py中,我需要导入一个放置在路径/A/B/external.py下的外部模块。 'A' 和 'B' 只是文件夹,而不是包(没有 __ init__.py)。 最后假设/A/B/下也有一个utils.py文件,是external.py导入的。

如果我按照我熟悉的方式导入外部模块,我会这样做:

import sys
sys.path.append('/A/B/')
import external

问题是,当我尝试导入我的utils 模块时,python 会在 sys.modules dict 中找到它(因为外部导入了它),因此不会导入我的脚本,而只会导入 /A/B 下已经存在的脚本进口的。

现在,有解决方法。 我可能会更改模块的名称,或者将外部模块放在一个包中等等。但所有这些都感觉很脏。 我找不到做这些事情的“pythonic”最佳实践是什么。 正如你们中的一些人可能猜到的那样,在更复杂的情况下,它可能会导致非常烦人的错误。 另外,PEP8 不接受我熟悉的方式,因为模块顶部没有导入命令。

总之,我正在寻找做这些事情的最佳实践,谢谢。

虽然已经过去了将近两年,但我想描述一下我现在理解的正确答案。 TL;DR:最好的方法是完全避免操作sys.path (!),而是使用分发打包机制。

首先,让我们区分分发包和导入包。 一个import-package基本上是一个包含 pythonic 模块(即 .py/.pyc 文件)和一个__init__.py文件的目录,用于声明这个文件夹确实是一个包。 在问题的示例中,这是包含example.pyutils.py的目录。 与此相反,分发包是:

包含 Python 包、模块和其他用于分发版本的资源文件的版本化存档文件。

来源: PyPA 用户指南词汇表

另一个应该知道的术语是脚本 python 脚本是__main__ python 文件,它直接通过解释器运行(而其他 python 文件称为modules )。 来源: python 的文档

在您自己的导入包中,您不应编辑sys.path因为脚本文件会根据其文件的位置导入模块,而这正是所需的行为。 如果您打算使用导入包外部的另一个模块(并且让我明确表示,您从当前导入包内的另一个导入包导入的情况并非如此,这是正常行为并且运行良好),那么您应该将其作为已安装的分发包导入。

我的意思是,外部代码(在示例中,位于 A/B/ 下的 external.py 模块)应该作为分发包提供(它的维护者应该将它作为一个包上传到某个发行版机制,即PyPi ,这很可能是您,但作为另一个包开发人员)。 然后 - 您作为外部包用户应该安装它(例如在该外部分pip install的轮文件上使用pip install ),然后它将由您的环境添加和管理,以便您可以import external并且它可以在没有冲突的情况下工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM