2016-02-26 47 views
0

我已經完成了這一步,並與pdb跟蹤檢查每個值,但無法弄清楚爲什麼我得到一個KeyError,一切都有其預期的價值。這是函數:爲什麼當它有一個值時拋出一個KeyError?

def get_formatted_timestamp(date_field, time_field): 
    # expects date_field = yyyy-M-d 
    # expects time_field = H:m:s 
    # outputs yyyy-MM-ddTHH:mm:ss:SSSZ ('T' and 'Z' are literals) 
    dt = date_field.strip().split('/') 
    tm = time_field.strip().split(':') 
    if len(dt) != 3 or len(tm) != 3 or len(dt[0]) != 4: 
     print 'invalid date or time: {} {}'.format(date_field, time_field) 
     return '1900-01-01T00:00:00.000Z' # error date value 
    y = dt[0] 
    M = dt[1] if len(dt[1]) == 2 else '0'+dt[1] 
    d = dt[2] if len(dt[2]) == 2 else '0'+dt[2] 
    H = tm[0] if len(tm[0]) == 2 else '0'+tm[0] 
    m = tm[1] if len(tm[1]) == 2 else '0'+tm[1] 
    s = tm[2] if len(tm[2]) == 2 else '0'+tm[2] 
    return '{y}-{M}-{d}T{H}:{m}:{s}.000Z'.format(y, M, d, H, m, s) # KeyError 

的錯誤是:

KeyError: 'y' 

然而,y有一個適當的年份字符串值(我查repr(y);不出所料字符串)。我還檢查了dt[0]是有效的,它顯示了適當的年份價值。

爲什麼當所有事物都有預期值時拋出KeyError?我很難過。

這裏是PDB輸出,其中我手動檢查每一個值:

(Pdb) print repr(dt[0]) 
'2014' 
(Pdb) print repr(y) 
'2014' 
(Pdb) print repr(M) 
'02' 
(Pdb) print repr(d) 
'10' 
(Pdb) print repr(H) 
'15' 
(Pdb) print repr(m) 
'35' 
(Pdb) print repr(s) 
'19' 
+0

請注意,您可以只鍵入'DT [0]'在調試器提示符和PDB將已經使用'print repr(..)'作爲該值。對於'd'和's',分別使用'!d'和'!s',以避免這些被視爲調試器命令。出於這個原因,我總是在變量introspections前添加'!'。 –

+0

@MartijnPieters我不知道 - 謝謝! –

回答

5

你不關鍵y,因爲你沒有任何關鍵字參數。您只有位置參數。這不是一回事;即使您使用具有該名稱的變量,也並不意味着它也是關鍵字參數。

要麼使用數字來提取位置參數,要麼使用實際的關鍵字參數。如果你所有的局部變量匹配插槽名稱,您可以使用locals()提供這些關鍵字參數:

return '{y}-{M}-{d}T{H}:{m}:{s}.000Z'.format(**locals()) 

但除此之外,你必須給格式使用的實際關鍵詞的每個名字:

return '{y}-{M}-{d}T{H}:{m}:{s}.000Z'.format(y=y, M=M, d=d, H=H, m=m, s=s) 

請注意,您的代碼似乎重新創建了日期分析和日期格式化輪子。下面會做同樣的事情,但也驗證您有一個有效日期(例如閏年以外沒有2月29日等):

from datetime import datetime 

def get_formatted_timestamp(date_field, time_field): 
    # expects date_field = yyyy-M-d 
    # expects time_field = H:m:s 
    # outputs yyyy-MM-ddTHH:mm:ss.000Z ('T' and 'Z' are literals) 
    try: 
     dt = datetime.strptime('{} {}'.format(date_field, time_field), '%Y-%m-%d %H:%M:%S') 
    except ValueError: 
     return '1900-01-01T00:00:00.000Z' # error date value 
    return dt.strftime('%Y-%m-%dT%H:%M:%S.000Z') 
+0

D'oh!我應該意識到這一點。謝謝!我會將它標記爲在幾分鐘內讓我接受。 –

+0

另外,當日期/時間API使用衝突的符號時,它很混亂。 Joda對'M'和'm'使用相反的Python,而'S'是毫秒而不是秒。 –

+1

Python在這裏遵循C [strftime](http://linux.die.net/man/3/strftime)和[strptime](http://linux.die.net/man/3/strptime)函數;恐怕這是喬達的偏差。 –

相關問題