使用pickle从文件中加载、存储和删除配置参数

问题描述

我正在尝试保持我的应用程序的状态,到目前为止已经找到了 pickle 库。

我从 When using Python classes as program configuration structures (which includes inherited class attributes),a good way to save/restore?

中发现了如何设置和获取配置参数到字典中

我已经设法将它保存到外部配置文件中,但我认为我做得不对,而且感觉有点笨拙。

这是演示的简化版本:

配置文件

# https://stackoverflow.com/questions/50613665/when-using-python-classes-as-program-configuration-structures-which-includes-in

import pickle
from pathlib import Path

filename = 'config'

class Config(dict):
    __getattr__ = dict.__getitem__
    __setattr__ = dict.__setitem__
    __delattr__ = dict.__delitem__
    
    def __init__(self):
        # Load config from file 
        my_file = Path(filename)

        if my_file.is_file():
            infile = open(filename,'rb')
            self.update(pickle.load(infile))
            infile.close()    

    def __getstate__(self):
        return self

    def __setstate__(self,state):
        self.update(state)

    def save(self):
        # filename = 'config'  
        outfile = open(filename,'wb')
        pickle.dump(self,outfile)
        outfile.close() 

应用程序.py

import tkinter as tk
import pickle
from Config import Config

class App(tk.Tk):

    def __init__(self):
        tk.Tk.__init__(self)

        # Init config
        self.config = Config()
         
        # initalise variables from config
        param0 = tk.BooleanVar()
        self.getConfig(param0)

        param1 = tk.StringVar()
        self.getConfig(param1)

        param2 = tk.StringVar()
        self.getConfig(param2,"one")

        # Build config page   
        cb = tk.Checkbutton(self,text = "Param",variable=param0)
        cb.pack()
        
        e = tk.Entry(self,textvariable=param1)
        e.pack()
        
        om = tk.OptionMenu(self,param2,"one","two","three")
        om.pack()

    def getConfig(self,object,default=None):
        if str(object) in self.config:
            object.set(self.config[str(object)])
        else:
            if default:
                object.set(default)
        object.trace("w",lambda name,index,mode,object=object: self.setConfig(object))
        
    def setConfig(self,object):
        self.config[str(object)] = object.get()

        self.config.save()       

if __name__ == "__main__":
    app=App()
    app.mainloop()

这以我期望的方式工作,但是我不知道如何保存变量对象名称,而是将 python 生成名称存储在配置文件中,这只有在我只附加更多参数时才可以如果我在现有参数之间插入一个新参数,一切都会搞砸。

配置文件的示例输出

{'PY_VAR0': False,'PY_VAR1': 'test string','PY_VAR2': 'three'}

我想知道是否有更好的方法来做到这一点?

解决方法

我认为最好通过设置自己的变量名称而不是使用默认名称来为参数赋予有意义的名称:

例如

    param0 = tk.BooleanVar(name='boolean_param')
    param1 = tk.StringVar(name='string_param')
    param2 = tk.StringVar(name='user_choice')

会给你配置

{'string_param': 'test string','boolean_param': False,'user_choice': 'three'}

因此,即使您更改创建变量的顺序,也不会更改它们的名称,您仍然可以在配置文件中检索正确的值。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...