tags:

views:

53

answers:

1

Apologies for reposting but I had to edit this question when I got to work and realized I needed to have an account to do so. So here it goes again (with a little more context).

I'm trying to time how long a script takes to execute, and I am thinking of doing that by checking the elapsed time after every line of code is executed. I've done this before when the script has contained method definitions, but am not sure how it would work in this instance.

So my question is: Is there a way to use the setTrace() function in a script that has no method definitions? i.e.

for i in range(1, 100):
    print i

def traceit(frame, event, arg):
    if event == "line":
        lineno = frame.f_lineno
        print "line", lineno

    return traceit

sys.settrace(traceit)
+1  A: 

No, as the docs say, "The trace function is invoked (with event set to 'call') whenever a new local scope is entered" -- if you never enter a local scope (and only execute in global scope), the trace function will never be called. Note that settrace is too invasive anyway for the purpose of timing "how long a script takes to execute" as it will alter what it's measuring too much; if what you say is actually what you want, just take the time at start of execution and register with atexit a function that gets the time again and prints the difference. If what you want is different, i.e., profiling, see cProfile .

Further note that the code example you give couldn't possibly do anything useful (even though I've edited it to fix an indent error): first it loops, then it defs a function, finally it calls settrace... then immediately ends because there's no more code after that! If you want anything to happen before that loop start, and you want to have everything at module top level (bad idea, but, whatever), you have to put the "anything" lexically before the loop, not after...;-)

Alex Martelli
Thanks that's exactly what I was looking for! I'm not sure if 'atexit' is what I'm looking for though. I'm looking to continuously check the time, and if it's over a certain limit, then the script will terminate. It's mainly being used to check for infinite loops. What would you use to do that?
Leonidas
In Linux or any other Unix-y OS (==most any but windows), signal.alarm, see http://docs.python.org/library/signal.html?highlight=alarm#signal.alarm -- after signal.alarm(3600) for example you'll get a SIGALRM one hour later, you can handle it or let it kill your process. In Windows I guess I'd kludge it with a "sleeping thread" that kills the process if it ever wakes up after its timeout. In certain cases it's more solid to spawn a separate watchdog process (in case yours get wedged in an infinite non-interruptible wait outside of Python control).
Alex Martelli