[Python-3000] PEP 3119 - Introducing Abstract Base Classes
Barry Warsaw
barry at python.org
Fri Apr 27 16:16:55 CEST 2007
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On Apr 26, 2007, at 2:50 PM, Guido van Rossum wrote:
> After a fair amount of pre-discussion, I'm ready for the first
> official review of this PEP. The PEP is online at
> http://www.python.org/dev/peps/pep-3119/
Thanks for posting the PEP Guido. I haven't had time to follow the
mailing list discussions, so this PEP was a great way to understand
where you're heading with this proposal. Here are some comments.
I think there's a typo in the paragraph that introduces
__instancecheck__:
"The call isinstance(x, C) first checks whether C.__instancecheck__
exists, and if so, calls C.__subclasscheck__(x) instead of its normal
implementation."
I think the C.__subclasscheck__ there ought to be
C.__instancecheck__, right?
After reading the PEP, it's pretty clear to me that ABCs are
orthogonal to what /I've/ started using interfaces for, and that's
fine. If they can live together, as I think is the case, then cool.
There are a few things that I think are part of interfaces that
aren't part of ABCs:
- - Attributes. Interfaces allow you to make assertions about
attributes, not just methods, while ABCs necessarily cover only methods.
- - Documentation. Sure, you can docstring the abstract methods in an
ABC, but it's not the emphasis of the ABC. For me, the main strength
of interfaces is the emphasis on documenting the semantics of the
interfaces, methods, and attributes that contribute to the contract
you're asserting. Not just documenting them in off-line web pages,
but right there in the code.
There are of course plenty of other differences that people with more
experience can hash out. Some that draw me to using interfaces include:
- - The separation of inheritance and interface. ABCs conflate these
concepts while interfaces keep them separate. I like the separation
because it's clearer when reading the class definition which is
which. If I care about what the class promises, I look at its
interfaces. If I care about how the class keeps those promises, I
look at its base classes. With ABCs I think I'd have to look at
everything and suss out which is which.
- - With interfaces, you can make assertions about individual objects
which may be different than what their classes assert. Interface
proponents seem to care a lot about this and it seems there are valid
uses cases for it. For example, I've seen classes which map to a
database table, where certain instances might assert additional
properties (by adding interfaces) based on the value of a column.
Another example of separating inheritance and interface comes up when
you want to derive a subclass to share implementation details, but
you want to subtly change the semantics, which would invalidate an
ABC claim by the base class. Something like a GrowOnlyDictionary
that derived from dict for implementation purposes, but didn't want
to implement __delitem__ as required by the MutableMapping ABC.
Finally, I'm concerned with the "weight" of adding ABCs to all the
built-in types. There are two weights I'm thinking about: cognitive
weight for people (newbies, casual programmers) trying to understand
Python's built-in type system, and the weightiness of the additional
implementation details (new modules, lots of new classes and objects)
on applications that don't care about things like ABCs and
interfaces. Not everything is a framework! :)
I wonder if it would make sense or be possible to leave the built-in
types lightweight and ABC-free. The Python implementation itself
shouldn't care about ABCs, but any application, framework, or library
that does would be able to define their own MutableMappingDict which
derived from dict and MutableMapping. Or to promote consistency,
there could be an abclib module which provides these subclasses for
those applications and frameworks that care about them. Or we could
have a standard set of GFs, adaptors, whatever, which hide the
lightweightedness of the built-in types.
Cheers,
- -Barry
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (Darwin)
iQCVAwUBRjIF3XEjvBPtnXfVAQLySQP+MRhTdbZzYqZVfUQu1Pu++QmLu5+Tfiu0
DHoF6EBxeaghPpLT6XElYXG7AkFOWk18XajtJWUikaaSlgckujVpEJ7nEUh6dfue
rko3hiyy8XblHN4FjbGPkIja/+vgAdpFVpDIGBcNQouK1TPJ1pj7qfGPqoYpYdU2
7Woq2y9kIPU=
=sfLK
-----END PGP SIGNATURE-----
More information about the Python-3000
mailing list