如何在python

时间:2015-07-31 13:08:25

标签: python json runtime-error config python-3.4

我正在使用python 3.4我有问题阅读配置文件格式化的json格式(即不在同一行。) 我的配置文件'Example.config'就是这样的

[ABC]

outdoor = {'GAME':['cricket',
                    'football'],
           'INFO':[
                      {'Players':'eleven',
                       'Fun':'Unlimited'},
                      {'Players':'something',
                       'Fun':'Much_more'}
                     ]
         }

[XYZ]

INDOOR = {'GAME':['Carom'],
           'INFO':[
                        {'Players':'2','Fun':'Less'},
                        {'Players':'4','Fun':'More'}
                      ]
          }

INDOOR1 = {'GAME':['TABLE-TENNIS',
                    'BASKETBALL',
                    'ANYTHING'],
          'INFO':[
                    {'Players':'TWO','Fun':'MORE'},
                    {'Players':'MORE','Fun':'MUCHMORE'}
                     ]
         }

mycode的

config_parser=ConfigParser()
    config_parser.read('Example.config')
    for each_section in config_parser.sections():
        for option in config_parser.options(each_section):
            option=ast.literal_eval(option)
            try:
                games=option['GAME']
                info=option['INFO']
            except:
                print('PLease format config same as qa_config.config file.Please Pay special attention to casing')
                raise

            for game in games:
                for eachInfo in info:
                    _INFO=eachInfo['Players']
                    _FUN=eachInfo['Fun']
                    print (each_section,':\n')
                    print ('\t',game,':\n')
                    print ('\t',_INFO,':\n')
                    print ('\t',_FUN,':\n')

错误:

option=ast.literal_eval(option)
  File "C:\Python34\lib\ast.py", line 84, in literal_eval
    return _convert(node_or_string)
  File "C:\Python34\lib\ast.py", line 83, in _convert
    raise ValueError('malformed node or string: ' + repr(node))
ValueError: malformed node or string: <_ast.Name object at 0x02E61910>

如果我将字典保存在一行中作为字符串而没有在配置文件中进行任何美化ast.literal_eval()能够处理它。

例如:

outdoor = {'GAME':['cricket','football'],'INFO':[{'Players':'eleven','Fun':'Unlimited'},{'Players':'something','Fun':'Much_more'}]}

所以我猜这是由于我在配置文件中使用的制表符和空格。但是我需要在配置文件中进行美化,因为用户会更新它。

我也尝试过使用astevaljson.load。 T.I.A。

2 个答案:

答案 0 :(得分:2)

我尝试了你的代码和例子(诚然在2.7中)和问题 是你在错误的事情上使用ast.literal_eval()

您正在option上使用它,这是左侧的名称 ini文件(在您的示例中为单词outdoor,INDOOR和INDOOR1)。 您想在此选项的右侧上使用它。

将下面缺少的第二行添加到脚本中的相应循环中:

    for option in config_parser.options(each_section):
        option = config_parser.get(each_section, option)
        option = ast.literal_eval(option)

您的多行ini文件已完美解析。

答案 1 :(得分:0)

正如您所发现的,这不是有效的INI语法。如果您真的需要那种深度结构化的数据,请考虑使用YAML作为配置文件,如下所示:

ABC:
  outdoor:
    GAME:
       - cricket
       - football
    INFO:
      - Players: eleven
        Fun: unlimited
      - Players: something
        Fun: much more

并解析如下:

>>> import yaml
>>> with open('myconfig.yml') as fd:
...   config = yaml.load(fd)

您可以看到直接解析为Python数据结构:

>>> import pprint
>>> pprint.pprint(config)
{'ABC': {'outdoor': {'GAME': ['cricket', 'football'],
                     'INFO': [{'Fun': 'unlimited', 'Players': 'eleven'},
                              {'Fun': 'much more', 'Players': 'something'}]}}}