Simplifying anonymous inner classes?
Arnaud Delobelle
arnodel at googlemail.com
Sat Nov 1 10:50:39 EDT 2008
Tim Chase <python.list at tim.thechases.com> writes:
> 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?
>
> Thanks,
>
> -tkc
>
>
> PS: part of the aim is to have properties that can be discovered
> through introspection, know how to provide help on themselves, and
> have a protocol for parameter-discovery for the __call__ method.
Here's a way to do it in python 2.2+:
def instance(*args, **kwargs):
class MetaInstance(type):
pass
class Instance(object):
__metaclass__ = MetaInstance
@staticmethod
def MetaInstance__new__(meta, name, bases, attrs):
bases = list(bases)
bases.remove(Instance)
cls = type(name.capitalize(), tuple(bases), attrs)
return cls(*args, **kwargs)
MetaInstance.__new__ = MetaInstance__new__
return Instance
How to use it:
>>> class A(object):
... def foo(self): return 'A.foo'
...
>>> class b(instance(42), A):
... def __init__(self, x): print 'This B is given ', x
... def bar(self): return 'B.bar'
...
This B is given 42
>>> b.foo()
'A.foo'
>>> b.bar()
'B.bar'
>>>
(There may be a simpler way to do it, I've just adapted something else
to what you require)
--
Arnaud
More information about the Python-list
mailing list