为什么这会在它有值时抛出 KeyError?
Why is this throwing a KeyError when it has a value?
我已经逐步完成并使用 pdb trace 检查了每个值,但无法弄清楚为什么我会收到 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')
我已经逐步完成并使用 pdb trace 检查了每个值,但无法弄清楚为什么我会收到 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')