从文本文件中检索变量值的最佳方法 - Python - Json

时间:2009-05-29 06:48:30

标签: python json variables text-files

参考this question,我有一个类似但不一样的问题..

在我的路上,我会有一些文本文件,结构如下:

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类型?

请注意,我对文本文件结构有完全的自由,如果我提议的那个不是最好的,我可以使用我喜欢的格式。

编辑:ConfigParser可以是一个解决方案,但我不太喜欢它,因为在我的脚本中我将用

config.get("set", "var_name")

但我喜欢直接引用变量,就像我在python脚本中声明的那样......

有一种方法可以将文件导入为python字典吗?

哦,最后一点,请记住,我不知道文本文件中究竟有多少变量。

编辑2 :我对stephan的JSON解决方案非常感兴趣,因为通过这种方式,可以使用其他语言(PHP,然后通过AJAX JavaScript)简单地读取文本文件,但是在执行该解决方案时我失败了:

#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,。对一种语言没有限制。

11 个答案:

答案 0 :(得分:59)

  

但我喜欢的是引用变量direclty,因为我在python脚本中声明了它。

假设您很乐意稍微更改语法,只需使用python并导入“config”模块。

# myconfig.py:

var_a = 'home'
var_b = 'car'
var_c = 15.5

然后做

from myconfig import *

您可以在当前环境中按名称引用它们。

答案 1 :(得分:24)

使用ConfigParser。

您的配置:

[myvars]
var_a: 'home'
var_b: 'car'
var_c: 15.5

你的python代码:

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")

答案 2 :(得分:20)

您可以文本文件视为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
...

答案 3 :(得分:14)

使用JSONPyYAML将文件加载到字典the_dict中(请参阅此步骤的JSON或PyYAML文档,两者都可以存储数据类型)并将字典添加到您的全局字典中字典,例如使用globals().update(the_dict)

如果你想要它在本地字典中(例如在函数内),你可以这样做:

for (n, v) in the_dict.items():
    exec('%s=%s' % (n, repr(v)))

只要使用exec是安全的。如果没有,您可以直接使用字典。

答案 4 :(得分:5)

此处发布的其他解决方案对我不起作用,因为:

  • 我只需要一个普通脚本文件中的参数
  • import *对我不起作用,因为我需要一种方法来通过选择其他文件来覆盖它们
  • 只是一个带有词典的文件并不正常,因为我需要注释。

所以我最终使用了Configparserglobals().update()

测试文件:

#File parametertest.cfg:
[Settings]
#Comments are no Problem
test= True
bla= False    #Here neither

#that neither

这是我的演示脚本:

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

现在只有一个带有一个部分的文件,但这很容易采用。

希望对某人有所帮助:)

答案 5 :(得分:4)

假设您有一个名为“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

答案 6 :(得分:3)

您的格式有多可靠?如果分隔符始终是':',则以下操作。如果没有,相对简单的正则表达式应该可以胜任。

只要您使用相当简单的变量类型,Python的eval函数就会使文件的持久变量变得非常简单。

(下面给你一本字典,顺便说一句,你提到的是你最喜欢的解决方案之一。)

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

答案 7 :(得分:1)

您想要的是以下内容,但这是 NOT WOMMENDED

>>> for line in open('dangerous.txt'):
...     exec('%s = %s' % tuple(line.split(':', 1)))
... 
>>> var_a
'home'

这会产生与PHP register_globals类似的行为,因此具有相同的安全性问题。另外,我展示的exec的使用允许任意代码执行。如果你绝对确定在任何情况下都可以信任文本文件的内容,只有才能使用它。

您应该考虑将变量绑定到本地作用域,而不是绑定到对象,并使用解析文件内容的库,这样就不会执行任何代码。所以:选择此处提供的任何其他解决方案。

(请注意:我添加此答案不是作为解决方案,而是作为明确的非解决方案。)

答案 8 :(得分:1)

一种使用标准库从文本文件中读取变量的简单方法:

# Get vars from conf file
var = {}
with open("myvars.txt") as conf:
        for line in conf:
                if ":" in line:
                        name, value = line.split(":")
                        var[name] = str(value).rstrip()
globals().update(var)

默认情况下,这会将每个变量读取为字符串。如果您需要将它们转换为文字变量(例如列表/元组/布尔),那么您将需要使用 ast 模块:

import ast
ast.literal_eval(varname)

答案 9 :(得分:0)

如果要加载is in a subdirectoryis named with dashes的文件,

hbn的答案将不会开箱即用。

在这种情况下,您可以考虑以下方法:

exec open(myconfig.py).read()

或者更简单但在python3中弃用:

execfile(myconfig.py)

我猜Stephan202的警告适用于这两个选项,也许线上的循环更安全。

答案 10 :(得分:0)

如果数据具有常规结构,则可以逐行读取文件并填充您喜欢的容器。例如:

假设您的数据具有3个变量:x,y,i。

文件包含这些数据中的n个,每个变量在其单独的行上(每条记录3行)。这是两个记录:

384
198
0
255
444
2

这是将文件数据读入列表的方式。 (阅读文本,因此进行相应的投射。)

data = []
try:
    with open(dataFilename, "r") as file:
        # read data until end of file
        x = file.readline()
        while x != "":
            x = int(x.strip())    # remove \n, cast as int

            y = file.readline()
            y = int(y.strip())

            i = file.readline()
            i = int(i.strip())

            data.append([x,y,i])

            x = file.readline()

except FileNotFoundError as e:
    print("File not found:", e)

return(data)