2014-10-03 167 views
0

我一直在嘗試將我的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

回答

2

這裏有一種方法,使用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')) 
4

「或者是他們在做什麼,我試圖做的更好(但仍簡單)的方式?」

選項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
0

除了下面的答案,對於簡單的數據結構可以使用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模塊。