样式问题:包中的单个前导下划线

Style question: single leading underscore in a package

Python PEP 8 style guide 为方法名称中的单个前导下划线提供了以下指导:

_single_leading_underscore: weak "internal use" indicator. E.g. from M import * does not import objects whose names start with an underscore.

什么构成了"internal use"? 这是针对仅在给定 class 内调用的方法吗?

MyClass:

    def _internal_method(self):
        # do_something

    def public_method(self):
        self._internal_method()

继承方法如何 - 它们是否仍被视为 "internal"?

BaseClass:

    def _internal_method(self):
        # do something

MyClass(BaseClass):

    def public_method(self):
        self._internal_method()  # or super()._internal_method()

如果继承自软件包中的另一个模块怎么办?

file1.py

BaseClass:

    def _internal_method(self):
        # do something

file2.py

from file1 import BaseClass

MyClass(BaseClass):

    def public_method(self):
        self._internal_method()  # or super()._internal_method()

所有这些例子在技术上都很好,但它们在风格上都可以接受吗?你什么时候说前导下划线不是 necessary/helpful?

单个前导下划线是 Python 对 "private" 和 "protected" 变量的约定,在其他一些语言中可作为硬实现使用。

"internal use" 语言只是说你保留那个名字,作为开发者,你的代码可以随意使用,你的 module/code 的其他用户不能依赖与该名称相关的事物在以后的版本中以相同的方式运行,甚至存在。这只是 "protected" 属性的用例,但没有语言运行时的硬实现:用户应该知道 attribute/function/method 可以在没有任何事先警告的情况下更改。

因此,,只要使用您的 _ 前缀方法的其他 class 位于同一代码包中 - 即使在其他文件中, 或文件夹(其他完全不同的包),可以使用它们。

如果您有不同的 Python 包,即使密切相关,也不建议直接调用其他包的内部内容,从风格上讲。

至于限制,有时会有整个模块和 classes 不应该被您的 class 的用户使用 - 在这些模块上添加前缀会有些不利带有 _ 的模块 - 我会说,足以记录您的包用户应该调用的 public 接口,并在文档中添加某些部分 (modules/classes/functions)专为 "internal use and may change without note" 设计 - 无需干预他们的名字。

作为示例,我目前正在开发一个 set of tools/library for text-art on the terminal - 我将所有用户应该称为 public 的名称放在它的 __init__.py 中 - 其余的名称应该是 "internal".