views:

325

answers:

3

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 ?

+2  A: 
use no underscores for the external API,
one underscore for the subclassable API,
and two underscores for the private/internal API

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.

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

Nope, you can just use the double-underlined version and it will be munged automatically. It's ugly but it works.

bobince
+1  A: 

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.

Kozyarchuk
+2  A: 

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.

mithrandi