为什么当它有一个值时抛出一个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'
你不有关键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')
D'oh!我应该意识到这一点。谢谢!我会将它标记为在几分钟内让我接受。 –
另外,当日期/时间API使用冲突的符号时,它很混乱。 Joda对'M'和'm'使用相反的Python,而'S'是毫秒而不是秒。 –
Python在这里遵循C [strftime](http://linux.die.net/man/3/strftime)和[strptime](http://linux.die.net/man/3/strptime)函数;恐怕这是乔达的偏差。 –
请注意,您可以只键入'DT [0]'在调试器提示符和PDB将已经使用'print repr(..)'作为该值。对于'd'和's',分别使用'!d'和'!s',以避免这些被视为调试器命令。出于这个原因,我总是在变量introspections前添加'!'。 –
@MartijnPieters我不知道 - 谢谢! –