55

提到这个问题,我有一个类似但不一样的问题..

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

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 字典?

PS:我不喜欢使用 .py 文件的解决方案;我更喜欢 .txt、.inc、.whatever 不限于一种语言。

4

11 回答 11

99

但是我喜欢引用变量 direclty,正如我在 python 脚本中声明的那样。

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

# myconfig.py:

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

然后做

from myconfig import *

您可以在当前上下文中按名称引用它们。

于 2009-05-29T07:54:55.713 回答
32

您可以文本文件视为 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
...
于 2009-05-29T06:56:12.460 回答
32

使用配置解析器。

你的配置:

[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")
于 2009-05-29T06:57:58.403 回答
18

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

如果您希望它在本地字典中(例如在函数内部),您可以这样做:

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

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

于 2009-05-29T07:42:27.533 回答
7

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

  • 我只需要普通脚本文件中的参数
  • import *对我不起作用,因为我需要一种通过选择另一个文件来覆盖它们的方法
  • 只是一个带有 dict 的文件并不好,因为我需要在其中添加评论。

所以我最终使用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

它现在只是一个包含一个部分的文件,但这很容易采用。

希望它对某人有帮助:)

于 2012-08-03T16:21:55.587 回答
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
于 2012-03-22T03:43:22.323 回答
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
于 2009-05-29T08:27:04.040 回答
1

如果要加载的文件位于子目录中以 dashes 命名,则 hbn 的答案不会开箱即用。

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

exec open(myconfig.py).read()

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

execfile(myconfig.py)

不过,我猜 Stephan202 的警告适用于这两个选项,并且线路上的循环可能更安全。

于 2016-02-20T17:55:43.263 回答
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)
于 2021-02-18T20:09:04.993 回答
0

您想要的似乎是以下内容,但不推荐这样做:

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

这会产生与 PHP 有点相似的行为register_globals,因此具有相同的安全问题。此外,exec我展示的使用允许任意代码执行。当您绝对确定文本文件的内容在所有情况下都可以信任时才使用此选项。

您应该真正考虑将变量绑定到本地范围而不是对象,并使用解析文件内容的库,以便不执行任何代码。所以:使用此处提供的任何其他解决方案。

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

于 2009-05-29T07:55:57.770 回答
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)
于 2020-02-24T05:43:30.377 回答