python项目中的配置文件系统

参考项目为wukong-robot,这次是学习一下配置文件方面的知识。

设计思路

1.用什么格式的文件作为配置文件?

关于配置文件用什么格式,目前已经有很多种选择了:ini,yaml, json,xml,HOCON… 它们之间的比较和特点见这篇这篇,wukong-robot选择的是yaml格式作为配置文件, 但据说HOCON是目前最好的配置文件格式,以后我会考虑替换掉原来的yaml模式。

2. 配置文件存放到哪里?

这个可以自由选择,怎么方便怎么来就行,wukong-robot项目是存放到了一个自定义的隐藏文件夹中

3. 如何区分开发环境与应用环境

在开发的过程中因为用到了一些在线的服务,它们都需要一些各种各样的secretkey。这些已经属于是敏感信息了,不能就这样上传到Github。因此一个需求就是开发个过程中使用的配置文件与发布的配置文件不能相同。

4. 如何在不重启的情况下更新配置

wukong-robot 使用了watchdog来实现。 热更新配置文件的实现需要程序可以检测到配置文件的变化,watchdog刚好可以干这件事

代码构思

config.py模块:负责对配置文件的增删改查操作

config.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def reload():
pass

def init():
pass
def do_init():
pass
def get_path():
pass

def has_path():
pass

def has(item):
pass
def get_text():
pass
def dump(configStr):
pass

config_monitor.py 模块:它继承自FileSystemEventHandler 。FileSystemEventHandler 内置了一些文件系统事件的处理接口, 接口嘛,自然内容都是空的,自己选几个有用的去实现即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
class FileSystemEventHandler(object):
"""
Base file system event handler that you can override methods from.
"""

def dispatch(self, event):
"""Dispatches events to the appropriate methods.

:param event:
The event object representing the file system event.
:type event:
:class:`FileSystemEvent`
"""
self.on_any_event(event)
_method_map = {
EVENT_TYPE_MODIFIED: self.on_modified,
EVENT_TYPE_MOVED: self.on_moved,
EVENT_TYPE_CREATED: self.on_created,
EVENT_TYPE_DELETED: self.on_deleted,
}
event_type = event.event_type
_method_map[event_type](event)

def on_any_event(self, event):
"""Catch-all event handler.

:param event:
The event object representing the file system event.
:type event:
:class:`FileSystemEvent`
"""

def on_moved(self, event):
"""Called when a file or a directory is moved or renamed.

:param event:
Event representing file/directory movement.
:type event:
:class:`DirMovedEvent` or :class:`FileMovedEvent`
"""

def on_created(self, event):
"""Called when a file or directory is created.

:param event:
Event representing file/directory creation.
:type event:
:class:`DirCreatedEvent` or :class:`FileCreatedEvent`
"""

def on_deleted(self, event):
"""Called when a file or directory is deleted.

:param event:
Event representing file/directory deletion.
:type event:
:class:`DirDeletedEvent` or :class:`FileDeletedEvent`
"""

def on_modified(self, event):
"""Called when a file or directory is modified.

:param event:
Event representing file/directory modification.
:type event:
:class:`DirModifiedEvent` or :class:`FileModifiedEvent`
"""

在这个项目中主要是要用于检测配置文件改动,因此只实现了文件修改事件的处理接口。
描述: 检测到文件修改时,调用config的 reload()方法,并

config_monitor.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
from butler import config
from watchdog.events import FileSystemEventHandler


class ConfigMonitor(FileSystemEventHandler):
def __init__(self, conversation):
FileSystemEventHandler.__init__(self)
self._conversation = conversation

# 文件修改 事件处理逻辑, 这是个事件,每次文件被修改就会触发
def on_modified(self, event):
if not event.is_directory:
config.reload()
self._conversation.reload()

上面的configMonitor还需要配合Obsever使用,
observer属于watchdog,其 Schedule()方法可以监视路径并调用在给定事件处理程序中指定的适当方法以响应文件系统事件。event handler 指的是 事件处理器、 事件处理程序,也叫事件句柄

1
2
3
4
5

event_handler = ConfigMonitor(_conversation) # FileSystemEventHandler对象,
_observer.schedule(event_handler, constants.get_config_path(), False) # 为观察者指定观察目录以及事件管理器
_observer.schedule(event_handler, constants.DATA_PATH, False)
_observer.start()
鼓励一下:D