问题描述
.ini文件中有一个变量,它是具有日期格式的元组列表。我想在for循环中使用相同的内容,但会出错
示例INI文件
[VALUES]
date_range=[(2019-01-01,2019-12-31),(2020-01-01,2020-01-31),(2020-02-01,2020-02-28)]
脚本
import configparser
import ast
config = configparser.ConfigParser()
config.read('config_file.ini')
date_range = config.get('VALUES','date_range')
print("Date Range - "+date_range)
for tuple_val in date_range:
print("Tuple value - "+ tuple_val)
start,end = tuple_val
print("Start date - "+start+" and End date -"+ end)
上面给出了以下错误,因为从.ini文件中读取date_range值似乎被视为字符串。
Date Range - [(2019-01-01,2020-02-28)]
Tuple - [
Traceback (most recent call last):
File "sample.py",line 236,in <module>
for_loop()
File "sample.py",line 205,in for_loop
start,end = tuple_val
ValueError: not enough values to unpack (expected 2,got 1)
我尝试用ast.literal_eval()进行转换,但得到无效的令牌错误。对于实现预期结果的任何帮助,我们深表感谢。
date_range = ast.literal_eval(config.get('VALUES','date_range'))
解决方法
date_range
中的单个项目需要用引号引起来(例如,
"2019-01-01"
之前的literal_eval
)可以将它们视为字符串。
如果无法更改ini文件来执行此操作,则可以在读入它们后使用正则表达式替换来添加它们。
例如:
import re
...
date_range_s = re.sub('\(\s*(.*?)\s*,\s*(.*?)\s*\)',r'("\1","\2")',config.get('VALUES','date_range'))
date_range = ast.literal_eval(date_range_s)
在此替换之后的字符串date_range_s
的示例:
>>> print(date_range_s)
[("2019-01-01","2019-12-31"),("2020-01-01","2020-01-31"),("2020-02-01","2020-02-28")]
其余代码应按原样工作,并给出:
Start date - 2019-01-01 and End date - 2019-12-31
Start date - 2020-01-01 and End date - 2020-01-31
Start date - 2020-02-01 and End date - 2020-02-28
此正则表达式还将忽略项目周围的任何空格,因此,如果您有(2019-01-01,2019-12-31)
,则这不是问题,并且该空格最终不会构成字符串的一部分。
但是,请注意,此正则表达式不会测试是否已经存在引号,因此,如果您都在配置文件中提供字符串,并且也也使用正则表达式替换,那么您将再次破坏它。做一个或另一个。
还请注意,这不是n元素元组的通用解决方案。专门针对您在这里使用的2元素。
,这是另一种解决方案,
from ast import literal_eval
# convert into valid string's by adding appropriate quotes
date_range = (
config.get('VALUES','date_range').replace("(","('").replace(")","')")
)
# [('2019-01-01,2019-12-31'),('2020-01-01,2020-01-31'),('2020-02-01,2020-02-28')]
date_range = literal_eval(date_range)
for d in date_range:
start_date,end_date = d.split(",")
# print(start_date,end_date)