是否有命名单模块 Python 包的规则?

Posted

技术标签:

【中文标题】是否有命名单模块 Python 包的规则?【英文标题】:Are there rules for naming single-module Python packages? 【发布时间】:2016-02-16 05:19:39 【问题描述】:

我给 Python 包中唯一模块的名称应该与包的名称匹配吗?

例如,如果我有一个带有结构的单个模块的包

super-duper/
    super/
        __init.py___
        mycode.py
        ...

我可以在 PyPi 上创建一个包 super-duper,安装后,site-packages 中有两个名称不匹配的文件夹:

 super/
 super_duper-1.2.3.dist-info/

这意味着要导入我使用的项目

import super

而不是实际的包名(super_duper

这似乎违反了惯例(从我在 site-packages 中看到的所有其他软件包的早期文件夹来看)遵循该模式

 same_name/
 same_name-1.2.3.dist-info/

对于 PyPi 包same-name

我是否应该(总是)构建我的项目,以便

super-duper/
    super_duper/
        __init.py___
        mycode.py
        ...

确保包名和模块导入名“匹配”:

import super_duper

是否有我应该遵循的相关最佳实践或规则?

【问题讨论】:

【参考方案1】:

你的想法是对的。我见过的最常用的约定是:

/superduper
    /superduper
        __init__.py
        code.py
    /.git
    setup.py
    README.rst

您会发现大多数 Python 开发人员更喜欢模块名称(setuptools、pexpect、matplotlib 等)全部小写且没有特殊字符。 您的***项目文件夹也应该与 git repo 名称匹配,这样当您 git clone 时它​​不会改变。

我最好的建议是查看一些已建立好的项目的来源,并模仿他们所做的事情。

【讨论】:

【参考方案2】:

来自PEP 8:

首要原则

作为 API 的公共部分对用户可见的名称应遵循反映使用而非实现的约定。

包和模块名称

模块应该有简短的全小写名称。如果提高可读性,可以在模块名称中使用下划线。 Python 包也应该有简短的全小写名称,但不鼓励使用下划线。

这里似乎可以解决您的问题的唯一一件事是不鼓励在包名称中使用下划线。

目前还有其他 PEP 正在努力解决 Python 打包中的一些不一致问题(426、423),但在解决这些问题之前,我会选择PEP 20 下最有意义的方法.如果super 足以传达正在导入的内容,那么我会倾向于使用它(尽管如果是这种情况,为什么不将它也用于 PyPi 包名称?)。

我不认为惯例规定它们是相同的,但实际上它们都试图实现相同的目标,因此在大多数情况下最终结果相同。

【讨论】:

【参考方案3】:

据我所知,没有任何准则要求您的项目名称与已安装的包或模块相匹配。有一个deferred draft PEP-423 Naming conventions and recipes related to packaging,但这实际上被放弃了(从未应用过pending update)。

你说你看了,但你可能错过了一些现有的项目名称和包含的包不匹配的例子:

BeautifulSoup project 使用 beautifulsoup4 作为 PyPI 上的项目名称,它会安装包 bs4

dateutil Python package 在 PyPI 上可用作 python-dateutil。在 PyPI 项目名称前加上 python- 是相当普遍的,我今天在 PyPI 上统计了 1512 个这样的包。

Viivakoodi project 是 pyBarcode 的一个分支。他们的viivakoodi PyPI project 在site-packages 中安装了一个barcode 包。另一个这样的 fork 项目是Pillow,它是 Python Image Library 的一个 fork。它在 PyPI under that name 上可用,但该软件包安装了 PIL 软件包。

也就是说,我个人更喜欢 PyPI 项目名称和包含的包匹配;它减少了混乱。最值得注意的例外是项目分叉,其目的是维护旧包名称以简化迁移。

【讨论】:

第二个例子很有趣,因为它消除了我假设存在的一个等式:包名和 PyPi 上的名称之间。所以实际上有三件事:包名,PyPy 上的名称,以及与import 一起使用的名称,以使用包中的(单独)模型。我同意,到目前为止,最不令人困惑的是让所有三个都相同。【参考方案4】:

对您的问题的简短回答是:是的,让您的模块名称与单个模块包(应该是大多数已发布的包)的包名称相匹配通常是一个好习惯。

略长一点的答案是命名约定总是带有政治色彩的。在 Python 中定义语言标准的普遍接受的方法是一个称为“Python 增强建议”(PEP)的过程。 PEP 由一组 PEP 编辑管理,并通过publicly indexed 进行审核和评论。

目前,据我所知,只有一个“活动”(接受并实施)PEP 涵盖了模块命名约定,即 PEP 8:

模块应该有简短的全小写名称。下划线可以 如果它提高可读性,则在模块名称中使用。 Python 包 还应该有简短的全小写名称,尽管使用 不鼓励使用下划线。

但是,还有另一个提案仍在起草过程中,称为 PEP 423,它准确地推荐了您在帖子中陈述的内容:

每个项目只分发一个包(或只分发一个模块),并使用 包(或模块)名称作为项目名称。

它避免了项目名称与分布式包或模块名称之间可能发生的混淆。

它使名称保持一致。

很明确:当人们看到项目名称时,他会猜测包/模块名称,反之亦然。

它还限制了包/模块名称之间的隐含冲突。通过使用单个名称,当您向 PyPI 注册项目名称时,您 还执行基本的包/模块名称可用性验证。

请务必注意,此 PEP 仍处于“延期”状态,这意味着它被 PEP 编辑批准,并被另一个提案(特别是实施更新 PEP 440 中的模块元数据语法)。然而,自 423 最初的提案以来,这段时间没有起草任何竞争标准,而且大部分内容似乎都没有争议,所以我希望它在未来不会有太多重大变化而被接受。

【讨论】:

PEP 423 听起来不错。我对示例中句点 (.) 的使用感到困惑。我可以用super.duper 替换任何地方的super_duper 吗? PEP 423 被推迟,因为 PEP 426 正在起草中。然而,PEP 426 实际上已被放弃,但我担心这同样适用于 423。例如,从未应用过 some changes pending。 @raxacoricofallapatorius 示例中的句点实际上是命名空间——PEP 423 还建议如果包由单个实体拥有,则包名称的第一部分是所有者的名称。这有助于避免冲突,因此如果您制作了一个名为“pyramid”的包,而我制作了一个完全不同的名为“pyramid”的包,第三个用户可以同时安装这两个包并将它们区分开来。

以上是关于是否有命名单模块 Python 包的规则?的主要内容,如果未能解决你的问题,请参考以下文章

python变量命名规范

java 程序命名规则

python命名规则是啥?

Python代码规范与命名规则

ava包(package)的命名规范,java中package命名规则

python中模块和包的概念