2014-10-03 3 views
0

Я экспериментировал с путями хранения некоторых переменных из моего проекта python в текстовом файле, доступном для чтения/редактирования. Текстовый файл выкладывается так:Прочитать список из текстового файла

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

Как вы можете видеть, предназначается, чтобы быть строкой, а целое, и с списка. Код, который я до сих пор идет следующим образом:

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

Он разбивает строку в «=» и задает первый раздел в качестве имени переменной, а второй раздел в качестве значения этой переменной.

Однако, когда программа запускается, вместо того, чтобы выходить как целое число и список, b (123) и c ([4,5,6]) оба сохраняются как строки.

Есть ли способ преобразовать строки в их соответствующие типы? Или их лучший (но все же простой) способ делать то, что я пытаюсь сделать?

Любая помощь будет высоко оценена. Благодаря!

+1

Вы можете использовать 'eval', но есть груды угроз безопасности. – matsjoyce

+4

Посмотрите на ['ast.literal_eval'] (https://docs.python.org/3/library/ast.html#ast.literal_eval). В отличие от 'eval', он безопасен в использовании. – 5gon12eder

+0

может быть просто сделать функцию, которая говорит «эй, это список?» используя 'line.startswith (' [') '(или даже регулярные выражения, такие как босс), а затем используйте строковое управление для его сортировки и, в конце концов, int() для строковых ints, чтобы их окончательно преобразовать ...... было бы безопаснее, чем eval/exec, но на самом деле требуется работа – TehTris

ответ

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() dict. Вы должны keep data out of your variable names. Если вы хотите добавить переменные конфигурации в пространстве имен, вы можете использовать мою функцию следующим образом:

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

«Или их лучше (но простой) способ сделать то, что я пытаюсь сделать ?»

Вариант 1 Один простой и хороший способ заключается в использовании словаря в файле питона просто сделать импорт.

myConfig.py

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

В коде:

from myConfig import * 
print cfg['a'] 

Вы также можете использовать indvidual переменные вместо словаря и делать то же самое.

Вариант 2

Если вы не хотите, питон файл, который вы можете прочитать любой другой файл и использовать exec для выполнения команды построчно. Документы здесь: https://docs.python.org/2/reference/simple_stmts.html#exec

Вы можете использовать execfile, но я считаю, что оно прекращено в versoin 3.х Docs здесь: 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 модуля.

Смежные вопросы