On Friday, Apr 22, 2005, at 10:00 America/Chicago, Max Noel wrote:
Do you have a suggestion as to what can I give a module so it has enough information to execute a function that resides in __main__? Here is a visual of what is going on:
------__main__ def y1(): pass import foo foo.run(string_from_main) #what should I pass?
------external module, foo
def run(string_from_main): # exec(string_from_main) #y1 is run as if it were in __main__
/c
Python makes it easy to do because functions (and classes) are objects. Here:
# in __main__ def y1(): pass import foo foo.run(y1)
# in foo def run(functionFromMain): functionFromMain()
Yes, I know about this, but this is not the problem. The problem is knowing what *strings* to pass to the timeit module so it can access a function that is written in one's __main__. Basically, the timeit module uses a template to construct a function which is (in the timeit module) compiled and then executed. You get to send two strings: an initialization string that is run once and the code string that appears in a loop. Here, for example, is the function that is reconstructed and run without success (in mac's pythonIDE:
### def inner(_it, _timer): from __main__ import y1 # I supplied this _t0 = _timer() for _i in _it: y1() # and I supplied this _t1 = _timer() return _t1 - _t0 ###
The way the IDE works, this import fails. There are two ways I have found around the problem:
1) wrap the functions of __main__ into a triple quoted string and then parsing it apart and sending it to timeit (not too elegant/pythonic):
### brute force passing of function to timeit funcs='''
def y1(): print 'y1 executed' def y2(): print 'y2 executed' '''
for f in funcs.split('def'): f = f.strip() if not f: continue name = f.split('(')[0] t=timeit.Timer('def '+f) print name,t.timeit(1) ###
2) the other approach is to add an additional argument to the timeit __init__ that accepts globals() from the calling program:
###
def __init__(self, stmt="pass", setup="pass", timer=default_timer, glbls = globals):
"""Constructor. See class doc string.""" # changed here - -^
self.timer = timer
stmt = reindent(stmt, 8)
setup = reindent(setup, 4)
src = template % {'stmt': stmt, 'setup': setup}
self.src = src # Save for traceback display
code = compile(src, dummy_src_name, "exec")
ns = {}
exec code in glbls, ns # and here
self.inner = ns["inner"]
###
Then __main__ can send functions like this:
### def y1(): print 'y1 executed' def y2(): print 'y2 executed' for f in [y1,y2]: func = f.__name__ t=timeit.Timer(stmt = "%s()" % func, glbls = globals()) print func, t.timeit(1) ###
{If you read to here, thanks. Is there a better way to accomplish this with the current timeit module without modifying timeit? i.e. is there another way to pass the needed information as a string that timeit's created function can execute?}
/c
_______________________________________________ Pythonmac-SIG maillist - Pythonmac-SIG@python.org http://mail.python.org/mailman/listinfo/pythonmac-sig