设置 __all__ 然后使用前导下划线是否有意义?

Is there a point to setting __all__ and then using leading underscores anyway?

为了好玩和获利,我一直在阅读 cpython HTTP 包的源代码,并注意到在 server.py 中他们设置了 __all__ 变量,但也使用前导下划线作为函数 _quote_html(html).

这不是多余的吗?两者不都用来限制 from HTTP import * 导入的内容吗?

为什么他们两者都做?

__all__ 在做 from HTTP import * 时确实是一个限制;在函数或方法的名称前加上 _ 前缀是一种约定,用于通知用户该项目应被视为私有,因此使用时 his/her 风险自负。

除了具有 _leading_underscores"private-by-convention" 函数外,还有:

  • 相当多的 import 名字;
  • 四个class个名字;
  • 三个函数名不带前导下划线;
  • 两个字符串"constants";和
  • 一个局部变量(nobody)。

如果 __all__ 未定义为仅涵盖 classes,所有这些也将通过通配符 from server import * 添加到您的命名空间。

是的,您可以只使用其中一种方法,但我认为前导下划线比从 __all__ 中排除更有效;后者表示"you probably won't need this often",前者表示"keep out unless you know what you're doing"。他们都有自己的位置。

这主要是一个文档,与评论类似。前导下划线更清楚地表明 阅读代码 特定函数或变量不是 public API 的一部分,而不是让那个人检查每个反对 __all__ 的名字。 PEP8 明确建议以这种方式使用两种约定:

To better support introspection, modules should explicitly declare the names in their public API using the __all__ attribute. Setting __all__ to an empty list indicates that the module has no public API.

Even with __all__ set appropriately, internal interfaces (packages, modules, classes, functions, attributes or other names) should still be prefixed with a single leading underscore.