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 - [email protected] http://mail.python.org/mailman/listinfo/pythonmac-sig
