如何在每次读取时更新配置? [英] How to update configuration on each read?
问题描述
所以我有这门课:
import yaml
class Config():
def __init__(self, filename):
self.config_filename=filename
def __read_config_file(self):
with open(self.config_filename) as f:
self.cfg = yaml.safe_load(f)
def get(self):
self.__read_config_file()
return self.cfg
而且它工作正常.其背后的想法是每次我在配置中使用某些内容时强制重新读取配置文件.下面是一个用法示例:
And it works fine. The thought behind it is to force a reread of the config file every time I use something in the configuration. Here is an example of usage:
cfg = Config('myconfig.yaml')
for name in cfg.get()['persons']:
print (cfg.get()['persons'][name]['phone'])
print (cfg.get()['persons'][name]['address'])
这可行,但我认为它看起来非常难看.我可以这样做:
This works, but I think it looks extremely ugly. I could do something like this:
c = cfg.get()['persons']
for name in c:
print (c['persons'][name]['phone'])
print (c['persons'][name]['address'])
看起来好一点点,但我也失去了重新加载访问权限的好处,但我想做的是这样的事情(显然不起作用):
Which looks just a tiny bit better, but I also lose the benefit of reloading on access, but what I want to do is something this (which obviously does not work):
for name in c:
print (name['phone'])
print (name['address'])
似乎我不明白迭代字典的事情,但我主要关心的是每次使用该文件中的任何值时我都想重新加载配置文件,并且我希望它具有很好的可读性道路.那么我该如何重新设计它?
It seems like it's something I don't understand about iterating over dictionaries, but my main concern here is that I want to reload the configuration file each time any value from that file is used, and I want it in a nice readable way. So how can I redesign this?
配置文件示例.如有必要,可以在此处更改格式.
Example of configuration file. It's possible to change the format here if necessary.
persons:
john:
address: "street A"
phone: "123"
george:
address: "street B"
phone: "456"
推荐答案
用户 rasjani 发表了一些评论,帮助我解决了这个问题.我所做的基本上是这样的:
The user rasjani made some comments that helped me solve it. What I do is basically this:
import collections
class Config(collections.UserDict):
def __getitem__(self, key):
self.reload()
return super().__getitem__(key)
def reload(self):
with open(self.filename) as f:
c=yaml.safe_load(f)
super().__init__(c)
实际的类更复杂,有更多的错误检查和功能,但以上是我问的魔法是什么.
The actual class is more complicated with more error checking and features, but the above is what does the magic I asked about.
每次使用字典时都会调用方法 __getitem__
.所以我所做的只是在从超类调用 __getitem__
之前调用 reload
.
The method __getitem__
is called everytime you use the dictionary. So what I do is simply calling reload
before calling __getitem__
from the superclass.
这里有一个例外.
a = Config('myconf.yml')
b = a['field'] # Will reload the configuration file
c = a # But this will not
d = c['field'] # However, this will
我想通过同样的方式修改 __getattribute__
来解决这个问题,但我最终遇到了无穷递归的各种问题,实际上我不确定这是否是一个值得的问题解决,甚至根本解决问题.
I thought about solving that by also modifying __getattribute__
in the same way, but I ended up with all sorts of problems with endless recursion, and in practice I am not sure if it is a problem worth solving, or even a problem at all.
这篇关于如何在每次读取时更新配置?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!