为什么当它有一个值时抛出一个KeyError?

问题描述:

我已经完成了这一步,并与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我不知道 - 谢谢! –

你不关键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)函数;恐怕这是乔达的偏差。 –