从txt文件中读取参数

4
我有一个包含一些参数的txt文件。该txt文件如下所示:
par1 = 10.81
par2 = 0.3
par3 = 0.5 

我希望用Python读取该文件,并自动生成txt文件中指定的所有变量。

什么是最好的文件来读取配置文件并创建其中列出的参数?

特别是说,如果有一个类,如何实现以下内容?

class MyClass:
  def __init__(self)
     self.par1 = par1
     self.par2 = par2
     self.par3 = par3
4个回答

7

危险的代码在前方

您可以使用exec。考虑文件foo.txt

a = 1
b = 2
c = 3

以及代码:

with open('foo.txt') as f:
    for line in f:
        exec(line)
print(a)
# 1
print(b)
# 2
print(c)
# 3

但是,正如标题所说,这种方法很危险,因为foo.txt可以轻松地被修改以包含其他内容。

import os
os.remove('C:\system\a_very_important_system_file')

并且exec可以轻松执行它。

安全的做法

foo.txt更改为JSON格式:

{"a": 1,
 "b": 2,
 "c": 3}

使用json模块在代码中加载它:

import json

with open('foo.txt') as f:
    variables = json.load(f)

print(variables["a"])
# 1

编辑

如果您需要从未知的JSON文件动态初始化实例属性,可以使用setattr

import json

class MyClass:
    def __init__(self):
        with open('foo.txt') as f:
            variables = json.load(f)
        for key, value in variables.items():
            setattr(self, key, value)

谢谢。那么,在我的脚本中加载一些配置参数的最佳方法是什么?这些是类的参数。 - gabboshow
@gabboshow 我已经添加了使用 json 的正确和安全的方法。 - DeepSpace
我已经编辑了我的问题...在一个类的构造函数中是否可能实现它? - gabboshow
@gabboshow 是的,你可以在 __init__ 方法中读取文件。 - DeepSpace
如何将它们分配给self? - gabboshow
这意味着我应该已经知道 foo.txt 中的内容... 如果添加了新参数,我希望在不修改 init 的情况下,在我的类中可以使用 foo.txt 中的所有参数... 很抱歉之前表述不够清晰。 - gabboshow

0
除了@DeepSpace提供的答案外,您还可以使用正则表达式限制允许的值:
import re

string = """
par1 = 10.81
par2 = 0.3
par3 = 0.5 
"""

rx = re.compile(r'^(?P<key>\w+)\s*=\s*(?P<value>[\d.]+)', re.MULTILINE)

for var in rx.finditer(string):
    exec("{} = {}".format(var.group('key'), var.group('value')))

print(par1)
# 10.81

在这里,只允许使用数字值(0-9.)和变量名为a-z_。根据需要进行调整(例如允许字符串)。


另一种选择是使用参数的容器,即字典:

params = {match.group('key'): match.group('value')
            for match in rx.finditer(string)}
print(params)
# {'par1': '10.81', 'par2': '0.3', 'par3': '0.5'}

你可以通过 params['par1'] 调用你的变量。

-1

使用readlines()函数读取文件后

with open("sample.txt") as f:
    fr = f.readlines()

    fr = ['par1 = 10.81\n', 'par2 = 0.3\n', 'par3 = 0.5\n', 'par4 = 0.7\n', 'par5 = 0.9\n'] # Output

    fr = [f[:-1] for f in fr]

    frs = [f.split(" = ") for f in fr]

    for i, j in frs:
        exec("%s = %s" % (i,j))

使用 exec 是不安全的,应该尽量避免使用。 - DeepSpace
是的,你说得对,http://lucumr.pocoo.org/2011/2/1/exec-in-python/ 这篇文章解释了这个问题。 - Bijoy

-2

您正在寻找eval函数。
with open('foo.txt','r') as fil: for line in fil: eval(line)


1
几乎没有足够好的理由使用evalexec,包括这种情况。 - DeepSpace
漏了一行代码,也许现在会起作用了 @gabboshow - Priyank
同意 - 请参考@DeepSpace的答案。 - Priyank

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接