区分外部调用的对象方法和子类调用的对象方法的约定是什么?
我知道 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()
那么,你的约定是什么,编码方面、文档方面还是其他方面?
I know most of the ins and outs of Python's approach to private variables/members/functions/...
However, I can't make my mind up on how to distinguish between methods for external use or subclassing use.
Consider the following example:
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):
...
In this example, I want to make it clear that subscribe is a method to be used by external users of the class/object, while event is a method that should not be called from the outside, but rather by subclass implementations.
Right now, I consider both part of the public API, hence don't use any underscores. However, for this particular situation, it would feel cleaner to, for example, use no underscores for the external API, one underscore for the subclassable API, and two underscores for the private/internal API. However, that would become unwieldy because then the internal API would need to be invoked as
self._EventMixin__somePrivateMethod()
So, what are your conventions, coding-wise, documentationwise, or otherwise ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是一种合理且相对常见的做法,是的。 实际上,双下划线表示私有(与 C++ 术语中的“受保护”相对)实际上非常罕见。 您永远不会真正知道子类可能想要覆盖哪些行为,因此假设“受保护”通常是一个不错的选择,除非有充分的理由说明为什么干扰成员可能特别危险。
不,您可以只使用双下划线版本,它会自动被修改。 它很丑,但很有效。
This is a reasonable and relatively common way of doing it, yes. The double-underline-for-actually-private (as opposed to ‘protected’ in C++ terms) is in practice pretty rare. You never really know what behaviours a subclass might want to override, so assuming ‘protected’ is generally a good bet unless there's a really good reason why messing with a member might be particularly dangerous.
Nope, you can just use the double-underlined version and it will be munged automatically. It's ugly but it works.
我通常发现使用 double __ 会带来更多的麻烦,因为它使单元测试变得非常痛苦。 使用单个 _ 作为不属于特定类/模块的公共接口一部分的方法/属性的约定是我的首选方法。
I generally find using double __ to be more trouble that they are worth, as it makes unit testing very painful. using single _ as convention for methods/attributes that are not intended to be part of the public interface of a particular class/module is my preferred approach.
我想建议,当你发现自己遇到这种区别时,考虑使用组合而不是继承可能是一个好主意; 换句话说,实例化
EventMixin
(大概名称会改变)而不是继承它。I'd like to make the suggestion that when you find yourself encountering this kind of distinction, it may be a good idea to consider using composition instead of inheritance; in other words, instantiating
EventMixin
(presumably the name would change) instead of inheriting it.