[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