Лучший способ получить значения переменных из текстового файла?
Ссылаясь на этот вопрос, у меня есть аналогичная проблема, но не такая же проблема.
На моем пути у меня будет текстовый файл, структурированный как:
var_a: 'home'
var_b: 'car'
var_c: 15.5
И мне нужно, чтобы python читал файл, а затем создавал переменную с именем var_a со значением "home" и т.д.
Пример:
#python stuff over here
getVarFromFile(filename) #this is the function that im looking for
print var_b
#output: car, as string
print var_c
#output 15.5, as number.
Является ли это возможным, даже имея тип var?
Обратите внимание, что у меня есть полная свобода для текстовой файловой структуры, я могу использовать формат, который мне нравится, если тот, который я предложил, не самый лучший.
EDIT: ConfigParser может быть решением, но мне это не нравится, потому что в моем script я буду ссылаться на переменные в файле с
config.get("set", "var_name")
Но то, что я буду любить, - это напрямую ссылаться на переменную, поскольку я объявил ее в python script...
Есть ли способ импортировать файл в качестве словаря python?
О, последнее, помните, что я точно не знаю, сколько переменных у меня будет в текстовом файле.
Изменить 2. Меня очень интересует решение Stephan JSON, потому что таким образом текстовый файл можно читать просто с другими языками (например, PHP, а затем через JavaScript AJAX), но Во время выполнения этого решения я не могу что-то сделать:
#for the example, i dont load the file but create a var with the supposed file content
file_content = "'var_a': 4, 'var_b': 'a string'"
mydict = dict(file_content)
#Error: ValueError: dictionary update sequence element #0 has length 1; 2 is required
file_content_2 = "{'var_a': 4, 'var_b': 'a string'}"
mydict_2 = dict(json.dump(file_content_2, True))
#Error:
#Traceback (most recent call last):
#File "<pyshell#5>", line 1, in <module>
#mydict_2 = dict(json.dump(file_content_2, True))
#File "C:\Python26\lib\json\__init__.py", line 181, in dump
#fp.write(chunk)
#AttributeError: 'bool' object has no attribute 'write'
В каких проблемах я могу упасть с форматом JSON?
И как я могу прочитать массив JSON в текстовом файле и преобразовать его в python dict?
P.S: Мне не нравится решение, использующее файлы .py; Я предпочитаю .txt,.inc, что бы ни ограничивать один язык.
Ответы
Ответ 1
Загрузите файл JSON или PyYAML в словарь the_dict
(см. doc для JSON или PyYAML для этого шага, оба могут хранить тип данных) и добавить словарь в словарь глобалов, например используя globals().update(the_dict)
.
Если вы хотите использовать его в локальном словаре (например, внутри функции), вы можете сделать это следующим образом:
for (n, v) in the_dict.items():
exec('%s=%s' % (n, repr(v)))
если безопасно использовать exec
. Если нет, вы можете напрямую использовать словарь.
Ответ 2
Но то, что я буду любить, - это обратиться к переменной direclty, поскольку я объявил ее в python script..
Предполагая, что вы счастливы немного изменить свой синтаксис, просто используйте python и импортируйте модуль "config".
# myconfig.py:
var_a = 'home'
var_b = 'car'
var_c = 15.5
Тогда do
from myconfig import *
И вы можете ссылаться на них по имени в текущем контексте.
Ответ 3
Используйте ConfigParser.
Ваша конфигурация:
[myvars]
var_a: 'home'
var_b: 'car'
var_c: 15.5
Код вашего питона:
import ConfigParser
config = ConfigParser.ConfigParser()
config.read("config.ini")
var_a = config.get("myvars", "var_a")
var_b = config.get("myvars", "var_b")
var_c = config.get("myvars", "var_c")
Ответ 4
Вы можете рассматривать ваш текстовый файл как модуль Python и загружать его динамически, используя imp.load_source
:
import imp
imp.load_source( name, pathname[, file])
Пример:
// mydata.txt
var1 = 'hi'
var2 = 'how are you?'
var3 = { 1:'elem1', 2:'elem2' }
//...
// In your script file
def getVarFromFile(filename):
import imp
f = open(filename)
global data
data = imp.load_source('data', '', f)
f.close()
# path to "config" file
getVarFromFile('c:/mydata.txt')
print data.var1
print data.var2
print data.var3
...
Ответ 5
Другие решения, размещенные здесь, не работали для меня, потому что:
- Мне нужны только параметры из файла для обычного script
-
import *
не работал у меня, так как мне нужен способ переопределить их, выбрав другой файл
- Просто файл с dict не был прекрасен, так как мне были нужны комментарии.
Итак, я закончил использование Configparser
и globals().update()
Тестовый файл:
#File parametertest.cfg:
[Settings]
#Comments are no Problem
test= True
bla= False #Here neither
#that neither
И что мое демо script:
import ConfigParser
cfg = ConfigParser.RawConfigParser()
cfg.read('parametertest.cfg') # Read file
#print cfg.getboolean('Settings','bla') # Manual Way to acess them
par=dict(cfg.items("Settings"))
for p in par:
par[p]=par[p].split("#",1)[0].strip() # To get rid of inline comments
globals().update(par) #Make them availible globally
print bla
Это просто для файла с одним разделом, но это будет легко принять.
Надеюсь, что это будет полезно для кого-то:)
Ответ 6
Предположим, что у вас есть файл Called "test.txt" с:
a=1.251
b=2.65415
c=3.54
d=549.5645
e=4684.65489
И вы хотите найти переменную (a, b, c, d или e):
ffile=open('test.txt','r').read()
variable=raw_input('Wich is the variable you are looking for?\n')
ini=ffile.find(variable)+(len(variable)+1)
rest=ffile[ini:]
search_enter=rest.find('\n')
number=float(rest[:search_enter])
print "value:",number
Ответ 7
Насколько надежным является ваш формат? Если сепаратор всегда точно ":", то работает следующее. Если нет, достаточно простое регулярное выражение должно выполнить эту работу.
Пока вы работаете с довольно простыми типами переменных, функция eval Python делает сохраняющиеся переменные в файлах на удивление легкими.
(Ниже приведен словарь, кстати, вы упомянули одно из ваших предпочтительных решений).
def read_config(filename):
f = open(filename)
config_dict = {}
for lines in f:
items = lines.split(': ', 1)
config_dict[items[0]] = eval(items[1])
return config_dict
Ответ 8
То, что вы хотите, должно выглядеть следующим образом, но это НЕ РЕКОМЕНДУЕТСЯ:
>>> for line in open('dangerous.txt'):
... exec('%s = %s' % tuple(line.split(':', 1)))
...
>>> var_a
'home'
Это создает несколько схожесть с PHP register_globals
и, следовательно, имеет те же проблемы безопасности. Кроме того, использование exec
, которое я показал, позволяет выполнять произвольный код. Используйте это только в том случае, если вы абсолютно уверены, что содержимое текстового файла можно доверять при любых обстоятельствах.
Вы действительно должны рассматривать привязку переменных не к локальной области, а к объекту и использовать библиотеку, которая анализирует содержимое файла таким образом, чтобы код не выполнялся. Итак: перейдите к любому из других решений, представленных здесь.
(Обратите внимание: я добавил этот ответ не как решение, а как явное не-решение.)
Ответ 9
hbn answer не будет работать, если файл для загрузки находится в подкаталоге или с именем черточки.
В таком случае вы можете рассмотреть эту альтернативу:
exec open(myconfig.py).read()
Или более простой, но устаревший в python3:
execfile(myconfig.py)
Я полагаю, что предупреждение Stephan202 относится к обоим параметрам, и, возможно, цикл на линиях более безопасен.