2012-06-15 5 views
4

У меня есть простой скрипт Python, который использует обработчик сигнала для Ctl-C. Если программа завершается нормально, время окончания передается в функцию «print_results». Я хотел, чтобы функция print_results имела необязательный параметр, который, если он не передан, просто получает текущее «сейчас» время. Но когда я вызываю это из обработчика сигнала, он не получает правильное время.Значение параметра python по умолчанию с использованием datetime

Вот мой упрощен, но воспроизводимая программа:

import sys 
import signal 
import urllib2 
import urllib 
import datetime 
import time 
import getopt,sys 

def signal_handler(signal, frame): 
    print_results() 
    sys.exit(0) 

def print_results(ended=datetime.datetime.now()): 
    print "\nEnded at ",ended 
    print "Total time: ",(ended - startTime) 
    print "Finished ",numIterations," iterations, received ",totalRecords," records" 

    numIterations = 0 
    maxIterations = 8 
    delaySecs = 3 
    totalRecords = 0 

    # set up signal handler 
    signal.signal(signal.SIGINT, signal_handler) 

    startTime = datetime.datetime.now() 

    print "Starting at ",time.asctime(time.localtime()) 

    while (numIterations < maxIterations): 

     iterStartTime = datetime.datetime.now() 

     numIterations += 1 

     print "Iteration: ",numIterations 

     # sleep if necessary 

     if delaySecs > 0: 
      time.sleep(delaySecs) 

     iterEndTime = datetime.datetime.now() 

     print "Iteration time: ",(iterEndTime - iterStartTime) 

    endTime = datetime.datetime.now() 

    print "Ended at ",time.asctime(time.localtime()) 
    print "Total test time: ",(endTime - startTime) 

    print_results(endTime) 

Вот что происходит, когда я типа CTL-C

$ python test.py               
Starting at Fri Jun 15 08:28:15 2012 
Iteration: 1 
Iteration time: 0:00:03.003101 
Iteration: 2 
Iteration time: 0:00:03.003105 
Iteration: 3 
^C 
Ended at 2012-06-15 08:28:15.766496 
Total time: -1 day, 23:59:59.999964 
Finished 3 iterations, received 0 records 

Похоже, что, когда print_results вызывается без аргументов, значение 'finished' не интерпретируется правильно как объект datetime. Но поскольку у Python нет способа сделать (насколько я могу судить), я не могу сказать, что не так.

Спасибо заранее,

Митч

+2

Изменение 'в то время как (numIterations

+1

... или xrange, для python 2.x –

+0

... и избавиться от' numIterations + = 1'. – martineau

ответ

23

Проблема у Вас есть то, что вы оцениваете функцию в параметре. Это означает, что ended=datetime.datetime.now() берет значение времени, когда оно разбирается, а не когда оно вызывается. То, что вы должны сделать, это что-то вроде этого:

def print_results(ended=None): 
    if ended is None: 
     ended = datetime.datetime.now() 
    ... 

Здесь есть действительно хорошее объяснение того, почему это происходит: “Least Astonishment” in Python: The Mutable Default Argument

+4

[Это очень много] (http://stackoverflow.com/questions/1132941/least-astonishment-in-python-the-mutable-default-argument). – JoeFish

+0

@JoeFish Действительно хорошая ссылка, thx! Я добавил его к ответу. –

+0

Спасибо ... это имеет смысл, но я, очевидно, ожидал, что он будет оценен во время выполнения ... – mitchmcc

Смежные вопросы