2016-05-13 15 views
0

Ich habe einen Code geändert, den ich auf Stackoverflow here gefunden habe, aber ich bekomme ein seltsames Verhalten. Kann jemand meinen Fehler sehen?Python Zeitvariable ändert sich nicht

import atexit 
from time import clock 

line = "="*10 + ">>>" 

def secondsToStr(s): 
    return "{0}.{1}ms".format(round(s*1000), round(s*1000000)) 

## 
# @brief Starts a timer. If the program crashes, the end function will be called anyway. 
def start(): 
    atexit.register(stop) 
    print(line,"Start time measurement") 
    startTime = clock() 
    print("new start time:", startTime) 

## 
# @brief Needs to be called after start(). Prints the time passed since start() was called. 
def stop(): 
    end = clock() 
    elapsed = end-startTime 
    print(startTime, end) # Inserted for debugging 
    print(line, "Ellapsed time:", secondsToStr(elapsed)) 
    atexit.unregister(stop) 

def now(): 
    return secondsToStr(clock()) 

startTime = clock() 

Die Idee ist start() und stop() zu nennen, die Zeit das Programm dauert zwischen diesen beiden Calles zu messen. Seltsamerweise ändert sich die startTime nicht. Somit gibt jeder Anruf von stop() die vergangene Zeit seit dem ersten Anruf von start() an. Hier ist ein Beispiel für die Ausgabe:

==========>>> Start time measurement 
new start time: 0.285078 
Doing work 
0.231932 1.766478 
==========>>> Ellapsed time: 1535.1534546ms 

==========>>> Start time measurement 
new start time: 1.766624 
More work 
0.231932 1.975752 
==========>>> Ellapsed time: 1744.1743820ms 

==========>>> Start time measurement 
new start time: 1.975821 
More work 
0.231932 1.976301 
==========>>> Ellapsed time: 1744.1744369ms 

Warum ist die startTime Wechsel nie? Es sollte jedes Mal einen neuen Wert erhalten, wenn start() aufgerufen wird.

+2

Haben Sie gelernt, was eine lokale Variable ist? – user2357112

Antwort

1

Der Grund, warum es nicht funktioniert, ist, weil innerhalb start, startTime eine lokale Variable ist. Wenn Sie die globale Variable aktualisieren möchten, müssen Sie Python sagen, dass ausdrücklich:

def start(): 
    global startTime # tell python to work with `startTime` in the global scope. 
    atexit.register(stop) 
    print(line,"Start time measurement") 
    startTime = clock() 
    print("new start time:", startTime) 

ist jedoch zu beachten, dass 99% der Zeit, wenn Sie die global Anweisung verwenden, gibt es wahrscheinlich eine bessere Alternative. Ohne Ihren genauen Anwendungsfall zu kennen, ist es schwierig, einen perfekten Vorschlag zu geben. Aber ich könnte einen Kontextmanager betrachten hier:

import contextlib 
from time import clock 

line = "="*10 + ">>>" 

def secondsToStr(s): 
    return "{0}.{1}ms".format(round(s*1000), round(s*1000000)) 

@contextlib.contextmanager 
def timer(): 
    start = clock() 
    try: 
     yield None 
    finally: 
     stop = clock() 
     print(line, "Ellapsed time:", secondsToStr(elapsed)) 

Sie würden diese wie folgt verwenden:

with timer(): 
    do_something() 
    do_something_else() 

und nach den Funktionen zurückkehren, werden Sie die kombinierte Laufzeit der beiden Funktionen erhalten gedruckt . Wie bei Ihrem Original wird dies weiterhin gedruckt, wenn eine Ausnahme auftritt.

+0

Vielen Dank, Ihre Lösung mit dem Contextmanager ist sehr sauber – Jonas

-1

Geben Sie unter Unix die aktuelle Prozessorzeit als Gleitkommazahl in Sekunden zurück. Die Genauigkeit und eigentlich die Definition der Bedeutung von "Prozessorzeit" hängt von der gleichnamigen C-Funktion ab, aber in jedem Fall ist dies die Funktion, die zum Benchmarking von Python- oder Timing-Algorithmen verwendet wird.

Dies bedeutet, dass die time.clock() die Zeit von Anfang an gemessen hat. Wenn Sie die Wandzeit messen möchten, können Sie time.time() verwenden

Verwandte Themen