关于从文本文件中检索变量值的最佳方法:从文本文件中检索变量值的最佳方法 – Python – Json

Best way to retrieve variable values from a text file - Python - Json

谈到这个问题,我有一个相似但不相同的问题。

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

1
2
3
var_a: 'home'
var_b: 'car'
var_c: 15.5

我需要python读取该文件,然后创建一个名为var_a、值为'home'的变量,依此类推。

例子:

1
2
3
4
5
6
#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可以是一个解决方案,但我不太喜欢它,因为在我的脚本中,我必须用

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

但是我喜欢的是直接引用变量,正如我在Python脚本中声明的那样…

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

哦,最后一件事,记住我不知道在文本文件中到底有多少个变量。

编辑2:我对Stephan的JSON解决方案很感兴趣,因为通过这种方式,文本文件可以用其他语言(例如php,然后通过ajax-javascript)简单地读取,但是我在执行该解决方案时失败了:

1
2
3
4
5
6
7
8
9
10
11
12
13
#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,。任何对一种语言没有限制的解决方案。


But what i'll love is to refer to the variable direclty, as i declared it in the python script..

假设您愿意稍微更改语法,只需使用python并导入"config"模块即可。

1
2
3
4
5
# myconfig.py:

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

那就去吧

1
from myconfig import *

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


使用ConfigParser。

您的配置:

1
2
3
4
[myvars]
var_a: 'home'
var_b: 'car'
var_c: 15.5

您的python代码:

1
2
3
4
5
6
7
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")


您可以将文本文件视为python模块,并使用imp.load_source动态加载它:

1
2
import imp
imp.load_source( name, pathname[, file])

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 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
...


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

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

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

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


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

  • 我只是需要一个普通脚本文件中的参数
  • import *不适合我,因为我需要一种方法通过选择另一个文件来覆盖它们。
  • 只是一份有口述的文件不太好,因为我需要在里面写评论。
  • 小精灵

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

    测试文件:

    1
    2
    3
    4
    5
    6
    7
    #File parametertest.cfg:
    [Settings]
    #Comments are no Problem
    test= True
    bla= False    #Here neither

    #that neither

    这是我的演示脚本:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    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

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

    希望它对某人有帮助:)


    假设您有一个名为"test.txt"的文件,其中包含:

    1
    2
    3
    4
    5
    a=1.251
    b=2.65415
    c=3.54
    d=549.5645
    e=4684.65489

    你想找到一个变量(A,B,C,D或E):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    ffile=open('test.txt','r').read()

    variable=raw_input('Wich is the variable you are looking for?
    '
    )

    ini=ffile.find(variable)+(len(variable)+1)
    rest=ffile[ini:]
    search_enter=rest.find('
    '
    )
    number=float(rest[:search_enter])

    print"value:",number


    你的格式有多可靠?如果分隔符始终正好是":",则以下操作有效。如果不是,一个相对简单的regex应该完成这项工作。

    只要使用相当简单的变量类型,python的eval函数就可以让将变量保存到文件中变得非常容易。

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

    1
    2
    3
    4
    5
    6
    7
    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


    您想要的是以下内容,但不建议这样做:

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

    这就产生了与PHP的register_globals相似的行为,因此也存在相同的安全问题。另外,我展示的exec的使用允许任意代码执行。只有在您完全确定文本文件的内容在任何情况下都可以被信任时才使用此选项。

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

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


    如果要加载的文件在子目录中,或者用破折号命名,HBN的答案将不会开箱即用。

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

    1
    exec open(myconfig.py).read()

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

    1
    execfile(myconfig.py)

    不过,我想Stephan202的警告适用于这两种选择,也许在线循环更安全。