Simplifying anonymous inner classes?
Peter Otten
__peter__ at web.de
Sat Nov 1 08:44:41 EDT 2008
Tim Chase wrote:
> I've got code similar to the following
>
> class Action:
> def __init__(self, ...): pass
> def __call__(self, ...): pass
> def get_help(self, ...): pass
>
> class Backend:
> class _Load(Action):
> def __init__(self, ...): pass # override1
> def __call__(self, ...): pass # override1
> def get_help(self, ...): pass # override1
> load = _Load(...)
> class _Run(Action):
> def __call__(self, ...): pass # override2
> def get_help(self, ...): pass # override2
> run = _Run(...)
>
> class DatabaseBackend(Backend):
> class _Frob(Action):
> def __init__(self, ...): pass # override3
> def __call__(self, ...): pass # override3
> def get_help(self, ...): pass # override3
> frob = _Frob(...)
>
> In certain other languages, I might reach for an anonymous inner
> class -- however, I don't see any way to do something like
>
> class Backend:
> load = (class Action:
> def __init__(self, ...): pass # override1
> def __call__(self, ...): pass # override1
> def get_help(self, ...): pass # override1
> )(...args to __init__...)
> run = ...
>
> It seems silly to define the inner classes _Load and _Run just to
> create a single instance of them (and for all it matters the
> _Load and _Run could be promptly deleted from the containing
> namespace immediately after instantiation). Method
> implementations are sufficiently complex that a lambda won't
> suffice (or if they would, they're beyond my know-how).
>
> Is there a more Pythonic way to instantiate sub-classes and
> provide instance-specific implementations without the overhead of
> an unused "anonymous" class cluttering my code/namespace?
Python 2.6 has class decorators:
>>> class instantiate(object):
... def __init__(self, *args):
... self.args = args
... def __call__(self, class_):
... return class_(*self.args)
...
>>> class Backend:
... @instantiate(1,2)
... class load:
... def __init__(self, x, y):
... self.x = x
... self.y = y
... def __str__(self):
... return "load(%s, %s)" % (self.x, self.y)
...
>>> print Backend.load
load(1, 2)
For older Pythons you can put the class into a function:
>>> class instantiate:
... def __init__(self, *args):
... self.args = args
... def __call__(self, make_class):
... return make_class()(*self.args)
...
>>> class Backend:
... @instantiate(1,2)
... def load():
... class Load:
... def __init__(self, x, y):
... self.x = x
... self.y = y
... def __str__(self):
... return "load(%s, %s)" % (self.x, self.y)
... return Load
...
>>> print Backend.load
load(1, 2)
While the class namespace isn't "cluttered" it's all a bit too complex to be
truly pythonic.
Peter
More information about the Python-list
mailing list