1

我知道 Python 处理私有变量/成员/函数/...的方法的大部分来龙去脉。

但是,我无法决定如何区分外部使用的方法或子类使用的方法。

考虑以下示例:

class EventMixin(object):
    def subscribe(self, **kwargs):
        '''kwargs should be a dict of event -> callable, to be specialized in the subclass'''

    def event(self, name, *args, **kwargs):
        ...

    def _somePrivateMethod(self):
        ...

在这个例子中,我想明确指出 subscribe 是一个由类/对象的外部用户使用的方法,而 event 是一个不应该从外部调用的方法,而应该由子类实现调用。

现在,我认为这两个部分都是公共 API,因此不要使用任何下划线。但是,对于这种特殊情况,例如,外部 API 不使用下划线,可子类化 API 使用一个下划线,私有/内部 API 使用两个下划线会感觉更简洁。但是,这将变得笨拙,因为需要调用内部 API

self._EventMixin__somePrivateMethod()

那么,您的约定是什么,编码方面、文档方面或其他方面?

4

3 回答 3

3
use no underscores for the external API,
one underscore for the subclassable API,
and two underscores for the private/internal API

这是一种合理且相对普遍的做法,是的。实际私有的双下划线(与 C++ 术语中的“保护”相反)在实践中非常罕见。您永远不会真正知道子类可能想要覆盖哪些行为,因此假设“受保护”通常是一个不错的选择,除非有充分的理由说明与成员搞乱可能特别危险。

However, that would become unwieldy because then the internal API would
need to be invoked as self._EventMixin__somePrivateMethod()

不,你可以只使用双下划线的版本,它会自动被修改。这很丑陋,但它有效。

于 2008-10-25T13:26:57.710 回答
2

我通常发现使用 double __ 会带来更多麻烦,因为它使单元测试非常痛苦。使用单个 _ 作为不打算成为特定类/模块的公共接口一部分的方法/属性的约定是我的首选方法。

于 2008-10-25T15:45:28.280 回答
2

我想提出的建议是,当您发现自己遇到这种区别时,考虑使用组合而不是继承可能是个好主意;换句话说,实例化EventMixin(可能名称会改变)而不是继承它。

于 2008-10-26T12:48:00.323 回答