Python 包名称约定

Posted

技术标签:

【中文标题】Python 包名称约定【英文标题】:Python package name conventions 【发布时间】:2011-02-12 10:06:05 【问题描述】:

是否有像 Java 的 com.company.actualpackage 这样的 Python 包命名约定?大多数时候,我会看到简单的、可能相互冲突的包名称,例如“web”。

如果没有这样的约定,有什么理由吗?您如何看待在 Python 世界中使用 Java 命名约定?

【问题讨论】:

【参考方案1】:

Python 有两个涵盖该主题的“咒语”:

显式优于隐式。

命名空间是一个很棒的主意——让我们做更多这样的事!

在The Python Style Guide (PEP 8) 中有一个命名和导入模块的约定。

没有这样的约定来始终如一地以 Java 样式为模块名称添加前缀的最大原因是,随着时间的推移,您的代码中最终会出现很多实际上不需要的重复。

Java 的一个问题是它迫使您不断重复自己。 Java 代码中有很多样板文件,这些样板文件在 Python 中是不需要的。 (Getter/setter 就是一个典型的例子。)

命名空间在 Python 中不是什么大问题,因为您可以在导入时为模块指定别名。如:

import com.company.actualpackage as shortername

因此,您不仅可以在程序中创建或操作命名空间,还可以创建您自己的节省击键的别名。

【讨论】:

【参考方案2】:

Java 的约定也有其自身的缺点。并非每个开源软件包背后都有一个稳定的网站。如果他的网站发生变化,维护者应该怎么做?此外,使用此方案包名称会变得很长且难以记住。最后,包的名称应该代表包的用途,而不是它的所有者

【讨论】:

之所以使用域名,是为了使用项目所有者控制下的名称空间。但是,如果站点与包名称不同,那将是令人困惑的...... @deamon 答案中的问题是,如果您没有可以控制的域名,您会怎么做——这对许多人来说都是如此 这不是问题。使用 Maven 和 Gradle,您始终知道从哪里获取 projectX 包。版本 1 可能是 org.place1,版本 2 可能是 com.startup.projectX 等...我在过去 2 个月里进行 Python 编程,我已经发现至少 10 个名称冲突的项目,所以他们不得不更改名称正因为如此。使用 tld.domain.etc 架构可以很好地避免这种情况。【参考方案3】:

其他任何来寻找此内容的人的更新:

截至 2012 年,PEP 423 解决了这个问题。 PEP 8 简单地谈到了这个话题,但只是说:全部小写或下划线。

要点:选择 PyPI 上尚未使用的令人难忘、有意义的名称。

【讨论】:

【参考方案4】:

Python 包没有类似 Java 的命名约定。您当然可以为您自己开发的任何包采用一个,但您可能必须侵入性地编辑您可能从第三方采用的任何包,并且“文化上陌生的”命名约定可能会削弱您自己的包的更改以被广泛采用在您的组织之外。

从技术上讲,Java 在 Python 中的约定并没有什么问题(它只会让一些 from 语句更长一点,没什么大不了的),但在实践中,文化方面使它几乎不可行。

【讨论】:

【参考方案5】:

通常没有包层次结构的原因是 Python 包不容易以这种方式扩展。包是实际的目录,尽管您可以让包在多个目录中查找子模块(通过将目录添加到包的__path__ 列表中),但这并不方便,而且很容易出错。至于为什么 Python 包不容易以这种方式扩展,嗯,这是一种设计选择。 Guido 不喜欢深度层次结构(现在仍然不喜欢)并且认为它们没有必要。

惯例是选择一个明显但对您的项目唯一的***包名称 - 例如,项目本身的名称。您可以根据需要构建其中的所有内容(因为您可以控制它。)将包拆分为具有不同所有者的单独部分需要更多工作,但有一些指导方针是可能的。很少需要。

【讨论】:

【参考方案6】:

如果您愿意,没有什么可以阻止您使用该约定,但它在 Python 世界中根本不是标准的,您可能会得到有趣的外观。当它们深深嵌套在 com 中时,对包进行管理并不是很有趣。

对于来自 Java 的人来说,这可能听起来很草率,但实际上它似乎并没有造成任何大的困难,即使是像 web.py 这样名称不佳的包。

在实践中,您经常命名空间冲突的地方是相对导入:package.module1 中的代码尝试使用import module2,而package.module2module2 在标准库(通常是标准库,因为标准库很大并且还在增长)。幸运的是,模棱两可的相对导入 are going away.

【讨论】:

Ehm,考虑到绝对导入必须显式打开,因此偶然执行绝对导入而不是相对导入有点困难。常见的问题是相反的:尝试从具有同名模块的包中导入 stdlib 模块。这不是由于缺少包层次结构引起的(因为您就在其中的一个包中),而是 Python 在 3.x 中摆脱了隐式相对导入。 啊,是的,同意...重新措辞。【参考方案7】:

我已经使用 python 多年了,我看到的 99.9% 的冲突来自试图将文件命名为“xml.py”的新开发人员。我可以看到 Java 方案的一些优势,但大多数开发人员都足够聪明,可以选择合理的包名称,所以这真的不是什么大问题。

【讨论】:

“xml.py”问题(命名一个意外隐藏内置模块的脚本)更多是由于脚本是模块正在搜索模块的脚本目录,而不是不明显的名字。将脚本命名为 'xml.py' 的人通常不会期望它会使用 'import xml' 导入。 有经验的开发人员不会将脚本命名为 'xml.py' 并期望执行 'import xml',但我明确表示这对新开发人员来说是个问题。

以上是关于Python 包名称约定的主要内容,如果未能解决你的问题,请参考以下文章

Python 包名称约定

如何解释 PyPi 包名中的命名约定

pyjnius 通过包名获取其他应用程序的名称

pyjnius 通过包名获取其他应用程序的名称

python第十六天

Android - 包名称约定