我有一个如下定义的列表:
header_fields = [
['delim',0,4,'strip()'],
['qual',4,5,None],
['NLS_CODE',6,25,'strip()'],
['source_system_id',26,45,'strip()'],
['extract_name',46,65,'strip()'],
['extract_serial_number',66,85,'strip()'],
['file_counter',86,88,"lstrip('0')"],
['total_file_count',89,91,'strip()'],
['extract_run_date_time',92,126,'strip()'],
['from_date',127,161,'strip()'],
['thru_date',162,196,'strip()'],
['number_of_rows',197,216,'strip()'],
['data_recons1',217,246,'strip()'],
['data_recons2',247,276,'strip()'],
['data_recons3',277,306,'strip()']
]
元素[1]和元素[2]用于解析名为header
的行
我想为header_fields
中的每个元素调用元素[3],如下所示:
for element in header_fields:
a = header[element[1]:element[2]]
if element[3] None:
b = a
else:
b = eval('a.'+element[3])
有没有办法重组所有这些以避免评估? ast.literal_eval('a.'+element[3])
抛出'格式错误的字符串'
答案 0 :(得分:4)
只需使用函数(当需要预绑定参数时使用functools.partial
或lambda
)而不是名称。 E.g:
['delim',0,4,str.strip],
['qual',4,5,None],
['NLS_CODE',6,25,str.strip],
['source_system_id',26,45,str.strip],
['extract_name',46,65,str.strip],
['extract_serial_number',66,85,str.strip],
['file_counter',86,88, lambda s: s.lstrip('0')],
... etc ...
然后,您当前正在尝试
b = eval('a.'+element[3])
使用,而不是
b = element[3](a)
如果您确定知道您总是想在a
上调用方法(可能带参数),您可以使用基于getattr
的其他方法(以方法名称作为字符串),例如;但这种方法更为通用。
答案 1 :(得分:4)
有很多方法。考虑到目前的情况,最直截了当的可能就是使用getattr
:
header_fields = [
['delim',0,4,'strip'],
['qual',4,5,None],
['NLS_CODE',6,25,'strip'],
['source_system_id',26,45,'strip'],
['extract_name',46,65,'strip'],
['extract_serial_number',66,85,'strip'],
['file_counter',86,88,'lstrip', ('0',)],
['total_file_count',89,91,'strip'],
['extract_run_date_time',92,126,'strip'],
['from_date',127,161,'strip'],
['thru_date',162,196,'strip'],
['number_of_rows',197,216,'strip'],
['data_recons1',217,246,'strip'],
['data_recons2',247,276,'strip'],
['data_recons3',277,306,'strip']
]
然后:
for element in header_fields:
a = header[element[1]:element[2]]
if element[3] is None:
b = a
else:
args = element[4] if len(element) > 3 else ()
b = getattr(a, element[3])(args)
在这里,我在[{1}}中隐藏了论据,以便element[4]
提供'0'
。
就我个人而言,我可能会倾向于重组一些,也可能按Alex Martelli's answer中的建议使用lstrip
。