2017-03-07 92 views
3

我有一個包含一些參數的txt文件。 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 

回答

3

危險代碼AHEAD

你可以使用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 

BUT,作爲標題說,這是一種危險的方法,因爲foo.txt可以很容易地修改,以包含

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

exec會很高興地執行它。

安全APPROACH

變化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) 
+0

謝謝。那麼什麼是在我的腳本中加載一些配置參數的最好方法?這些是一個類的參數.. – gabboshow

+0

@gabboshow我已經添加了正確和安全的方式來使用'json'來完成它。 – DeepSpace

+0

我編輯了我的問題......是否有可能在類的構造函數中完成它? – gabboshow

-1

您正在尋找評估函數。
with open('foo.txt','r') as fil: for line in fil: eval(line)

+0

這給出語法錯誤......並且不會創建變量.. – gabboshow

+0

幾乎沒有足夠的理由使用'eval'或'exec',包括這個用例。 – DeepSpace

+0

錯過了一行,也許現在這將工作@ gabboshow – Priyank

-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)) 
+0

使用exec是不安全的,應該不惜一切代價避免。 – DeepSpace

+0

是的,你是正確的http://lucumr.pocoo.org/2011/2/1/exec-in-python/,這解釋了它。 – Bijoy

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']打電話給你的變量。