Inheriting and modifying lots of methods

F

Felipe Ochoa

I need to create a subclass from a parent class that has lots of
methods, and need to decorate all of these. Is there pythonic way of
doing this other than:

def myDecorator (meth):
@wraps(meth)
def newMeth (*args, **kw):
print("Changing some arguments here.")
return meth(newargs, **kw)
return newMeth

class Parent:
def method1(self,args):
pass
def method2(self,args):
# and so on...
def methodn(self,args):
pass

class Mine(Parent):
for thing in dir(Parent):
if type(eval("Parent."+thing)) == type(Parent.method1):
eval(thing) = myDecorator(eval("Parent." + thing))

I'm not even sure that this works! Thanks a lot!
 
D

Diez B. Roggisch

Felipe said:
I need to create a subclass from a parent class that has lots of
methods, and need to decorate all of these. Is there pythonic way of
doing this other than:

def myDecorator (meth):
@wraps(meth)
def newMeth (*args, **kw):
print("Changing some arguments here.")
return meth(newargs, **kw)
return newMeth

class Parent:
def method1(self,args):
pass
def method2(self,args):
# and so on...
def methodn(self,args):
pass

class Mine(Parent):
for thing in dir(Parent):
if type(eval("Parent."+thing)) == type(Parent.method1):
eval(thing) = myDecorator(eval("Parent." + thing))

I'm not even sure that this works! Thanks a lot!

It's not working, you can't assign to something eval'ed.

There are various options here, including metaclasses, but I think the
simplest is to write a simple function:

def decorate_methods(subclass):
for name in dir(subclass):
thing = getattr(subclass, name)
if isinstance(thing, types.MethodType):
setattr(subclass, name, myDecorator(thing)) # maybe
myDecorator(thing.im_func) is better here


Simply invoke that function with "Mine" - or use a metaclass to do that
implicitly.

Diez
 
S

Steven D'Aprano

I need to create a subclass from a parent class that has lots of
methods, and need to decorate all of these. Is there pythonic way of
doing this other than:

def myDecorator (meth):
@wraps(meth)
def newMeth (*args, **kw):
print("Changing some arguments here.") return meth(newargs,
**kw)
return newMeth

class Parent:
def method1(self,args):
pass
def method2(self,args):
# and so on...
def methodn(self,args):
pass

class Mine(Parent):
for thing in dir(Parent):
if type(eval("Parent."+thing)) == type(Parent.method1):
eval(thing) = myDecorator(eval("Parent." + thing))

I'm not even sure that this works! Thanks a lot!


eval() won't work there. exec might, but any time you think you need eval/
exec, you probably don't :)

You can probably do some magic with metaclasses, but the simplest
solution would be something like this:

class Mine(Parent):
pass


import types
for name in dir(Mine):
attr = getattr(Mine, name)
if type(attr) in (types.MethodType, types.UnboundMethodType):
setattr(Mine, name, myDecorator(attr))


The above (probably) won't touch classmethods and staticmethods.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,962
Messages
2,570,134
Members
46,692
Latest member
JenniferTi

Latest Threads

Top