sách gpt4 ai đã đi

python - 如何在大型 python 项目中构建导入

In lại 作者:行者123 更新时间:2023-12-03 20:25:43 27 4
mua khóa gpt4 Nike

我已经阅读了很多关于 Python 导入的“操作方法”文章(以及相关的 SO 问题),但是我正在努力弄清楚在大型 Python 项目中管理导入的“最佳实践”是什么。例如,假设我有一个如下所示的项目结构(这过于简单化了):

test/                     
packA/
subA/
__init__.py
sa1.py
sa2.py
__init__.py
a1.py
a2.py
packB/
b1.py
b2.py
main.py

并在里面说 packA/subA/sa1.py我想从 packB/b1.py 导入代码.更一般地说,我希望能够在项目内的包/子包之间自由导入。

根据我目前的理解,有四种方法可以做到这一点:

选项1

将我的项目根目录永久添加到 PYTHONPATH 并在项目中的任何地方使用绝对导入。所以在 packA/subA/sa1.py 我会有
from packB import b1
随着项目树变大,这可能会有点困惑,例如
from packB.subC.subD.subE import f1
选项 2

与上面相同,但我没有修改 PYTHONPATH 以包含项目根目录,而是坚持只从项目根目录执行 python(因此根目录始终是工作目录)。

选项 3

使用相对导入
from ...packB import b1
我不喜欢这个,因为它不容易阅读,而且我读过的所有地方通常都说相对导入是一个坏主意。

选项 4

使用 setuptools/setup.py 脚本并使用 pip 安装我的包,这样我就可以在任何地方导入。

这似乎有点矫枉过正,因为所有代码都已经在项目文件夹中(并且每次包更改时都必须重新安装)并且还可能导致依赖项/版本管理令人头疼。

所以我的问题是,以上哪一项(如果有的话)被认为是最佳实践?我目前在 1 和 2 之间犹豫不决,但很高兴听到更优雅/Pythonic 的方法。

注:我正在使用 Python 3.6

1 Câu trả lời

重新设计
您可以做的第一件事是重新设计您的包裹。说真的,直接来自 pep20 python zen :

Flat is better than nested.


因此,您应该尝试减少包中嵌套文件夹的数量。例如 from mypackage.module1.module2.module3 import foo不应该存在。唯一一次您会看到嵌套在非常大且成熟的包中的模块,例如 django。或 tensorfow .即便如此,您会注意到它们的 api 仍然非常短(即 from django.test import TestCase ),即使它们的内部模块是复杂且嵌套的。通常,长且嵌套的导入是 Python 中不良包设计的信号。
另外,如果包 A 和包 B 相互依赖(相互依赖),它们应该真的在同一个包下,你需要重新考虑你的设计选择。

我的意见
我总是喜欢遵循 flask 的标准。或 keras 图书馆。 keras特别是 API 对我来说一直很直观。我经常去那个 repo 来激发我自己的编码实践。就个人而言,我尝试尽可能使用相对导入,因为我构建的大多数东西都很小(没有嵌套,或者一层嵌套)。但是我知道许多较大的项目选择使用绝对导入,因为它们有更多的嵌套层。
我从“keras”库中采用的一件事是进口的特异性和可用性之间的平衡。导入 Conv2D层它不是那么普遍: from keras import Conv2D ,
但它也不是那么具体: from keras.layers.convolational import Conv2D中间有一个很好的: from keras.layers import Conv2D .
但是,如果我们仔细查看 keras ,您会注意到 Conv2D类仍然包含在它自己的文件中 convolutional.py .他们可以通过在 __init__.py 中添加以下行来降低导入的特异性。层模块:
from .convolutional import Conv2D
这允许您保留用于开发的包/模块结构,但保持客户端 api 简单直观。

使用点
绝对不要 选择选项 1。 pip 包的目的是您不需要将随机路径添加到您的 PYTHONPATH .这不是可扩展的,这意味着代码将无法在其他机器上运行或作为独立包而不编辑 PYTHONPATH .最好有 setup.py在每个包中并通过 pip 安装东西.
一直要 pip uninstall . 真的很烦人和 pip install .每次您对包裹进行更改时,这就是为什么 pip-e旗帜:
pip install -e .
-e flag 是一个可编辑的安装,它安装软件包,这样您对代码所做的任何更改都会立即生效,因此您不必保留 pip进行更改后卸载和重新安装。

关于python - 如何在大型 python 项目中构建导入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61759856/

27 4 0
行者123
Hồ sơ cá nhân

Tôi là một lập trình viên xuất sắc, rất giỏi!

Nhận phiếu giảm giá Didi Taxi miễn phí
Mã giảm giá Didi Taxi
Giấy chứng nhận ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com