I would like to be able to specialize an existing class A, so as to obtain a
class B(A), with all methods of B being the methods of A preceded by a
special method of B called _before_any_method_of_A( self ), and followed by
a special method of B called _after_any_method_of_A( self ).
The goal is to avoid to redefine explicitly in B all methods of A.
Is this possible in Python?
Thanks a lot
Julien
--
python -c "print ''.join([chr(154 - ord(c)) for c in '*9(9&(18%.9&1+,\'Z
(55l4('])"
"When a distinguished but elderly scientist states that something is
possible, he is almost certainly right. When he states that something is
impossible, he is very probably wrong." (first law of AC Clarke)
Yes it's possible. The exact solution depends on how much control you
want, and over what. Do you want inheritance or delegation? Do you
want the same pre and post method for all inherited methods? Will you
always use single-inheritance? Would you mind using a list of names,
as a sort of midpoint between complete redefinition and completely
dynamic? Do you want class lookups to succeed? If so, what do you
want them to do?
Generally, you could build the class dynamically with a metaclass, or
use __getattr__ a lookup.
> I would like to be able to specialize an existing class A, so as to
> obtain a
> class B(A), with all methods of B being the methods of A preceded by a
> special method of B called _before_any_method_of_A( self ), and followed
> by
> a special method of B called _after_any_method_of_A( self ).
>
> The goal is to avoid to redefine explicitly in B all methods of A.
>
> Is this possible in Python?
Sure. After reading this (excelent!) article by M. Simionato
http://www.phyast.pitt.edu/~micheles/python/documentation.html you should
be able to write a decorator to make any method into a "sandwich"
(probably based on his "trace" example). Your code would look like this:
@decorator
def sandwich(f, self, *args, **kw):
self.before()
f(self, *args, **kw)
self.after()
class A:
@sandwich
def foo(self):
...
@sandwich
def bar(self, x):
...
Ok, but then you have to explicitely decorate every method. To avoid this,
you may use a metaclass; this article by Michael Foord explains how:
http://www.voidspace.org.uk/python/articles/metaclasses.shtml#a-method-decorating-metaclass
That's all!
--
Gabriel Genellina
I believe this would work (untested, 3.0):
class A(): # define methods
class B(): pass
func = type(lambda:None)
for item in A.__dict__:
if isinstance(item, func):
setattr(B, item.__name__, sandwich(item))
tjr
> Hi everybody,
>
> I would like to be able to specialize an existing class A, so as to
> obtain a class B(A), with all methods of B being the methods of A
> preceded by a special method of B called _before_any_method_of_A( self
> ), and followed by a special method of B called _after_any_method_of_A(
> self ).
>
> The goal is to avoid to redefine explicitly in B all methods of A.
>
> Is this possible in Python?
You may be able to adapt this code to do what you are after:
http://code.activestate.com/recipes/91192/
--
Steven
> Ok, but then you have to explicitely decorate every method. To avoid this,
> you may use a metaclass; this article by Michael Foord explains how:http://www.voidspace.org.uk/python/articles/metaclasses.shtml#a-metho...
Since Python 2.6 is out, I would recommend using a class decorator for
this task.
The class decorator is not inherited, so in order to decorate methods
in subclasses
one has to repeat it, which I see as a feature (explicit is better
than implicit).
Otherwise the readers of your classes will not have any visual clue
that something
magic is going on; moreover, you will lower the risk of decorating
methods
that should not be decorated (I mean, in case of accidents).
Michele Simionato
Good to know, I was not aware of the difference.
--
Gabriel Genellina