jimjjewett at gmail.com
Tue Aug 7 21:12:30 CEST 2012
On 8/6/12, Steven D'Aprano <steve at pearwood.info> wrote:
> On 07/08/12 08:55, Jim Jewett wrote:
>> One major use of an abstract class is to document an interface. The
>> abstract class can only define (or even document, really, if you value
>> docstrings) methods that it defines.
> I don't know that I accept that abstract classes are documentation. It seems
> to me that to be documentation, it has to be, well, documentation.
If the code is short and seems to be clear, many people will never
look at the external documentation. In that case, leaving surprises
out of the docstring is almost as bad as not documenting them at all.
> ... merely making something an abstract class is not in and of
> itself documentation.
Agreed, but that abstract class itself should clearly document the
contract that concrete implementations (and their users) must follow.
> But even putting that aside, the interface that it (implicitly?) documents
> is surely *required* interface.
Separating, for example, pen.draw from gunfighter.draw was one
of the primary use cases of abstract base classes.
_abcoll.py is dealing with infrastructure where python already defines
the double-underscore methods; for now, pretend it were an ordinary
domain module, using normal unreserved names.
A Container need not implement __len__. Since we're pretending
that the name wouldn't already be reserved by python, a concrete
Container could use the name for some domain-specific attribute,
such as LoudEngineNoise.
Every specialized container in the module (Sequence, Set, Mapping,
even MappingView) does need to have a __len__ method (ruling out
some factory objects). They even all define it with the name meaning,
by also inheriting from Sized.
I would prefer to see the name reserved and defined at the Container
level. It would still be OK to create a Container that could not tell you
its length, but it would not be OK to create a Container using __len__
for some other purpose.
For reasons that are no longer obvious, a MappingView needs to be
Sized, but does not need to be an Iterable or a Container. I haven't
yet seen a use for MappingView except to group the derived classes
KeysView, ItemsView, and ValuesView -- all of which are Iterable
Containers. KeysView and ItemsView also contain identical
Reusing the names associated with Iterable or Container (remember
we're pretending they weren't reserved by the double-underscore) for
some other use would be very confusing. So would reusing
_from_iterable, if it weren't semi-private.
MappingView should be able to reserve these names and forbid such
unrelated use. I'm not sure it needs to actually enforce the prohibition,
but it should be able to at least express the prohibition in a manner
visible to introspection.
* Well, identical code. I'm assuming that the expected input type differs.
More information about the Python-ideas