从文本文件中读取列表

问题描述:

我一直在尝试将我的python项目中的一些变量存储在用户可读/可编辑的文本文件中。该文本文件布局是这样的:从文本文件中读取列表

a = "hello" 
b = 123 
c = [4,5,6] 

正如你所看到的,是意味着是一个字符串,B的整数,和c的列表。我到目前为止的代码去如下:

for line in file: 
    name = line.split('=')[0] 
    value = line.split('=')[1] 
    vars()[name] = value 

它分裂在“=”行,并设置在第一部分作为变量名,并且所述第二部分作为该变量的值。但是,当程序运行时,b(123)和c([4,5,6])不是作为整数和列表出现,而是作为字符串保存。

有什么方法可以将字符串转换为适当的类型吗?或者他们是一个更好的(但仍然简单)做我想做的事情?

任何帮助将不胜感激。谢谢!

+1

您可以使用'eval',但是会附带一堆安全风险。 – matsjoyce 2014-10-03 18:44:22

+4

看看['ast.literal_eval'](https://docs.python.org/3/library/ast.html#ast.literal_eval)。不像'eval',使用起来很安全。 – 5gon12eder 2014-10-03 18:45:48

+0

也许只是做一个功能,说:“嘿,这是一个列表?”使用'line.startswith'''''(甚至像老板一样的正则表达式),然后使用字符串操作将它整理出来,最后int()放入弦乐器中以最终转换它们......会比eval/exec更安全,但实际上需要工作 – TehTris 2014-10-03 18:50:32

这里有一种方法,使用ast.literal_eval

import ast 
def config_file(filename): 
    result = {} 
    with open(filename) as f: 
     for line in f: 
      line = line.split('=',1) 
      result[line[0]] = ast.literal_eval(line[1].strip()) 
    return result 

print config_file('cfg.txt') 

你可能会想在for循环更多的牛肉,就像忽略空白行,删除注释等

另外请注意,这使数据在dict,而不是vars()字典。你应该keep data out of your variable names。如果你想给你的配置变量添加到您的命名空间,你仍然可以使用我的功能,像这样:

vars().update(config_file('cfg.txt')) 

“或者是他们在做什么,我试图做的更好(但仍简单)的方式?”

选项1 一个简单且有效的方法是使用在Python文件中的字典只是做进口。

myConfig.py

cfg={'a':"hello", 'b':123, 'c':[4,5,6]} 

在您的代码:

from myConfig import * 
print cfg['a'] 

您还可以使用indvidual变量而不是字典,做同样的。

选项2

如果你不想让你可以阅读任何其他文件,并使用exec由行执行命令行Python文件。 Docs here:https://docs.python.org/2/reference/simple_stmts.html#exec

您可以使用execfile,但我相信它会在版本3中停用。X文档浏览:https://docs.python.org/2/library/functions.html#execfile

选项3

您也可以使用其他的方法:

  1. 的Python ConfigParser:https://docs.python.org/2/library/configparser.html
  2. YAML文件:http://pyyaml.org/wiki/PyYAMLDocumentation
  3. XML文件:见举个例子: parsing XML configuration file using Etree in python

除了下面的答案,对于简单的数据结构可以使用json格式和词典或namedtuples:

import json 
from ast import literal_eval 
from collections import namedtuple 

json_vars = """{ 
    'a' : "hello", 
    'b' : 123, 
    'c' : [4,5,6] 
}""" 


print json_vars 
from_json = literal_eval(json_vars) 
# or: 
# from_json = json.loads(json_vars) 

variables = namedtuple('Vars', from_json.keys())(*from_json.values()) 

print variables 
print variables.a 
print variables.b 
print variables.c 

print variables._asdict() 
d = dict(variables._asdict()) 
print d 

print d['a'] 
print d.items() 


as_json_again = json.dumps(d, indent=2) 

print as_json_again 

对于更高级的对象,见pickle模块。