Are ABCs an anti-pattern?
Trent Nelson
trent at snakebite.org
Fri Oct 5 15:58:37 EDT 2012
On Tue, Oct 02, 2012 at 07:23:05AM -0700, Demian Brecht wrote:
> I don't use them anymore, but I'm curious about others opinions on this
> list...
I like them. In particular, I like that I can enumerate all the
subclasses that happen to implement the ABC via the metaclass's
__subclasses__() method. I also like that I can trust Python
not to instantiate a subclass of an ABC unless it meets all the
interface criteria I've stipulated.
Both of these aspects make ABCs a great fit when your base classes
will be subclassed by other users/libraries (i.e. that you have no
control over).
For example, I use them in a project of mine called Enversion in
order to automatically generate command-line scaffolding with as
little effort (programming/typing-wise as possible). The ABC
stuff lives in 'evn.cli' and provides a set of generic classes
for command-line tools.
One of the command line tools that ships with Enversion is the
'evnadmin' command. Thanks to all the ABC scaffolding in the
'evn.cli/command' module, all I need to write is the following
to get an 'evnadmin' command-line interface:
from evn.cli import (
CLI,
CommandLine,
)
class AdminCommandLine(CommandLine):
@property
def commands_module(self):
return evn.admin.commands
class AdminCLI(CLI):
@property
def program_name(self):
return 'evnadmin'
@property
def commandline_subclasses(self):
return AdminCommandLine.__subclasses__()
class DoctestCommandLine(AdminCommandLine):
_quiet_ = True
class DumpDefaultConfigCommandLine(AdminCommandLine):
pass
class DumpConfigCommandLine(AdminCommandLine):
_conf_ = True
class ShowConfigFileLoadOrderCommandLine(AdminCommandLine):
_conf_ = True
class DumpHookCodeCommandLine(AdminCommandLine):
_conf_ = True
_repo_ = True
[snip]
Running 'evnadmin' with no arguments yields this:
% evnadmin
Type 'evnadmin <subcommand> help' for help on a specific subcommand.
Available subcommands:
analyze
create
disable-remote-debug (drd)
doctest
dump-config (dc)
dump-default-config (ddc)
dump-hook-code (dhc)
enable
enable-remote-debug (erd)
find-merges (fm)
fix-hooks (fh)
root-info (ri)
run-hook (rh)
show-config-file-load-order (scflo)
show-repo-hook-status (srhs)
show-repo-remote-debug-sessions (srrds)
show-roots (sr)
toggle-remote-debug (trd)
version
The scaffolding can generate all of that automatically thanks to the
ability to enumerate __subclasses__() of a metaclass. The fact that
Python will bomb out if a derived class doesn't implement all the
required methods/properties is icing on the cake. When you are
expecting other developers to leverage your ABCs, getting instant
feedback when you forget to implement a required method/property
is incredibly useful. It's definitely not a case of battling the
design decisions made by the ABC author...
Relevant Python files:
https://github.com/tpn/enversion/blob/master/evn/cli.py
https://github.com/tpn/enversion/blob/master/evn/admin/cli.py
Regards,
Trent.
> Demian Brecht
> @demianbrecht
> http://demianbrecht.github.com
> --
> http://mail.python.org/mailman/listinfo/python-list
More information about the Python-list
mailing list