473,223 Members | 1,775 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,223 software developers and data experts.

run-time construction of methods

Hello all.

I am in the need of wrapping certain objects at run-time. My initial
approach was:

import inspect, new
def make_wrapper(obj, methodName):
cls = obj.__class__
wrapmth = getattr(obj, methodName)
print "************ ", methodName
def wrapper(self, *args, **kwargs):
print "**before ", methodName
return wrapmth(*args, **kwargs)
return wrapper

class Person(object):
def __init__(self, age):
super(Person, self).__init__()
self.age = age

def getAge(self):
return self.age

def setAge(self, newage):
"""sets the age of the person"""
self.age = newage

p = Person(33)
setattr(p, "setAge", new.instancemethod(make_wrapper(p,"setAge"), p,
p.__class__))
p.setAge(22)
print "age is ", p.getAge()

However, reflectional information is gone, such as the __doc__ string, and
in an interactive environment, when typing a method call of setAge() the
arguments are specified as "(..., ***)" rather than "(newage)"

I have thus attempted to replace the make_wrapper function with a version
where the inner function "wrapper" is a string which gets translated into
a function with an identical signature as the method to wrap.. my closest
attempt to a real solution is
def make_wrapper(obj, methodName):
cls = obj.__class__
wrapmth = getattr(obj, methodName)
print "************ ", methodName
wrapperstr = """def wrapper(self, *args, **kwargs):
print "**before ", methodName
return wrapmth(*args, **kwargs)"""
exec(wrapperstr, globals(), locals())
return wrapper

but I get the error

NameError: global name 'methodName' is not defined

which I don't know how to deal with... inspecting the locals() a
'methodName' is defined.. Note that my above 'solution' is far from the
product I want, I just figured I needed to get this to work, before
fidling with the signature stuff...
does anyone have an idea on how to approach this?
-Carlo
--
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Jul 18 '05 #1
1 1452
"Carlo v. Dango" <oe**@soetu.eu> writes:
Hello all.

I am in the need of wrapping certain objects at run-time. My initial
approach was:

import inspect, new
def make_wrapper(obj, methodName):
cls = obj.__class__
wrapmth = getattr(obj, methodName)
print "************ ", methodName
def wrapper(self, *args, **kwargs):
print "**before ", methodName
return wrapmth(*args, **kwargs)
return wrapper

class Person(object):
def __init__(self, age):
super(Person, self).__init__()
self.age = age

def getAge(self):
return self.age

def setAge(self, newage):
"""sets the age of the person"""
self.age = newage

p = Person(33)
setattr(p, "setAge", new.instancemethod(make_wrapper(p,"setAge"), p,
p.__class__))
p.setAge(22)
print "age is ", p.getAge()
I like the approach of using a bound method to p to create a
new instance specific method for p.
...
def make_wrapper(obj, methodName):
cls = obj.__class__
wrapmth = getattr(obj, methodName)
print "************ ", methodName
wrapperstr = """def wrapper(self, *args, **kwargs):
print "**before ", methodName
return wrapmth(*args, **kwargs)"""
exec(wrapperstr, globals(), locals())
return wrapper

but I get the error

NameError: global name 'methodName' is not defined

exec does not create a closure within the function calling it.
That is its downside. So everything is either local to wrapmth,
eg. parameters and variables created within the function, or
global. Fortunately you can still create a closure with exec
by declaring a function within a function. Here's my rewrite.
I hope it works for you.

def make_wrapper(obj, methodName):
cls = obj.__class__
wrapmth = getattr(obj, methodName)
print "********** ", methodName
wrapperstr = """\
def _closure(_wrapmth):
def wrapper(self, *args, **kwds):
"I wrap method %(methodName)s"
print "**before %(methodName)s"
return _wrapmth(*args, **kwds)
return wrapper
_wrapper = _closure(wrapmth)
""" % {'methodName': methodName} # Insert strings directly into code
locs = {'wrapmth': wrapmth} # Keep namespace clean to avoid conflicts
exec(wrapperstr, {}, locs)
return locs['_wrapper'] # and here is the result

See how the argument to _closure is the 'local' you want to keep
around. Also I don't use globals() or locals() directly since
they are cluttered. When you start trying to make the parameters
of wrapper meaningful you will want to minimize the chance
the parameter names conflict with other names within the scope
of the exec. That is also why _closure and _wrapmth begin
with underscores. You might want to choose even more cryptic names.
Also, inlining strings such as methodName instead of passing them
as variables into the exec scope reduces the chance of conflict.

Lenard Lindstrom
<le***@telus.net>
Jul 18 '05 #2

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Ed | last post by:
Hello, I took a course in asp about 2 years ago and I was practicing with IIS 5.0. Then I put it down for a while. Now trying to get back to it. I can't run asp files from subdirectories of...
4
by: Primo | last post by:
Hi, This problem has been frustrating me for days and I hope you experts can help me out. I am trying to run a command, which I would normally run from the command line, from within my C#...
6
by: orekin | last post by:
Hi There I have been trying to come to grips with Application.Run(), Application.Exit() and the Message Pump and I would really appreciate some feedback on the following questions .. There are...
3
by: emman_54 | last post by:
Hi every one, I am trying to run a batch file using my asp.net application. I am using the Process class to run the batch file. When I run my web application, In the task manager, i could see...
19
by: Bryan | last post by:
How can i run a bit of code straight from the IDE? Right now i make a temporary button and put the code behind that, then i run debug mode and click on the button. Is there a way to highlight...
9
by: Brett Wesoloski | last post by:
I am new to VS2005. I changed my program.cs file to be a different form I am working on. But when I go to run the application it still brings up the form that was originally declared as new. ...
7
by: Lee Crabtree | last post by:
I remember when I was first getting into .NET Forms programming that there was a rather emphatic rule about not constructing a form before calling Application.Run with it. So this: ...
8
by: David Thielen | last post by:
Hi; In our setup program how do I determine if I need to run "aspnet_regiis –i" and if so, is there an API I can calll rather than finding that program on the user's disk and calling it? --...
3
by: traceable1 | last post by:
Is there a way I can set up a SQL script to run when the instance starts up? SQL Server 2005 SP2 thanks!
7
by: mxdevit | last post by:
Task: run application from ASP.NET for example, you have a button on ASP.NET page, when press this button - one application is invoked. the code to run application (for example, notepad) is...
1
isladogs
by: isladogs | last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike...
0
by: veera ravala | last post by:
ServiceNow is a powerful cloud-based platform that offers a wide range of services to help organizations manage their workflows, operations, and IT services more efficiently. At its core, ServiceNow...
0
by: VivesProcSPL | last post by:
Obviously, one of the original purposes of SQL is to make data query processing easy. The language uses many English-like terms and syntax in an effort to make it easy to learn, particularly for...
3
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 3 Jan 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). For other local times, please check World Time Buddy In...
0
by: jianzs | last post by:
Introduction Cloud-native applications are conventionally identified as those designed and nurtured on cloud infrastructure. Such applications, rooted in cloud technologies, skillfully benefit from...
0
by: mar23 | last post by:
Here's the situation. I have a form called frmDiceInventory with subform called subfrmDice. The subform's control source is linked to a query called qryDiceInventory. I've been trying to pick up the...
0
by: fareedcanada | last post by:
Hello I am trying to split number on their count. suppose i have 121314151617 (12cnt) then number should be split like 12,13,14,15,16,17 and if 11314151617 (11cnt) then should be split like...
0
Git
by: egorbl4 | last post by:
Скачал я git, хотел начать настройку, а там вылезло вот это Что это? Что мне с этим делать? ...
1
by: davi5007 | last post by:
Hi, Basically, I am trying to automate a field named TraceabilityNo into a web page from an access form. I've got the serial held in the variable strSearchString. How can I get this into the...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.