tags: Python ConfigParser 配置 conf ini yaml properties 2019 年 11 月html
環境說明: Python2.7.11 CentOS7.6python
TODO 不一樣種類配置文件對比apache
YAML 是專門用來寫配置文件的語言,很是簡潔和強大,遠比 JSON 格式方便。數組
YAML 在 python 語言中有 PyYAML 安裝包。安全
YAML 語言(發音 /ˈjæməl/ )的設計目標,就是方便人類讀寫。它實質上是一種通用的數據串行化格式。數據結構
它的基本語法規則以下:
一、大小寫敏感
二、使用縮進表示層級關係
三、縮進時不容許使用 Tab 鍵,只容許使用空格。
四、縮進的空格數目不重要,只要相同層級的元素左側對齊便可
五、# 表示註釋,從這個字符一直到行尾,都會被解析器忽略,這個和 python 的註釋同樣app
YAML 支持的數據結構有三種:
一、對象:鍵值對的集合,又稱爲映射(mapping)/ 哈希(hashes) / 字典(dictionary)
二、數組:一組按次序排列的值,又稱爲序列(sequence) / 列表(list)
三、純量(scalars):單個的、不可再分的值。字符串、布爾值、整數、浮點數、Null、時間、日期函數
channelizer: org.apache.tinkerpop.gremlin.server.channel.HttpChannelizer graphs: { hugegraph: conf/hugegraph.properties, hugegraph1: conf/hugegraph1.properties, hugegraph2: conf/hugegraph2.properties, test01: conf/hugegraphtest01.properties, } maxAccumulationBufferComponents: 1024 maxChunkSize: 8192 maxContentLength: 65536 maxHeaderSize: 8192 maxInitialLineLength: 4096 metrics: consoleReporter: { enabled: false, interval: 180000 } csvReporter: { enabled: true, fileName: /tmp/gremlin-server-metrics.csv, interval: 180000, } gangliaReporter: { addressingMode: MULTICAST, enabled: false, interval: 180000 } graphiteReporter: { enabled: false, interval: 180000 } jmxReporter: { enabled: false } slf4jReporter: { enabled: false, interval: 180000 } plugins: [com.baidu.hugegraph]
Python3 官方 ConfigParser該模塊提供了實現基本配置語言的類,該類提供的結構相似於 Microsoft Windows INI 文件中的結構。可使用它來編寫可由最終用戶輕鬆定製的 Python 程序。post
ConfigParser 的一些問題:ui
注意事項
讀取配置文件
寫入配置文件
配置文件類型問題
[user] # section username = tom # key = val 或 key: val password = *** email = test@host.com [book] bookname = python bookprice = 25
Python 中正好沒有解析 properties 文件的現成模塊,因此單獨編寫了一個腳本用於讀寫 *.properties 文件
restserver.url=http://0.0.0.0:8080 # graphs list with pair NAME:CONF_PATH graphs=[test01:conf/hugegraphtest01.properties,hugegraph:conf/hugegraph.properties,hugegraph1:conf/hugegraph1.properties,hugegraph2:conf/hugegraph2.properties] # authentication #auth.require_authentication= #auth.admin_token= #auth.user_tokens=[]
# -* - coding: UTF-8 -* - u""" Python 讀寫 配置文件 邏輯說明: - read_config 讀取配置文件入口函數 - read_config_ini - read_config_yaml - write_config 寫入配置文件入口函數 - write_config_ini - write_config_yaml - 函數配置調用 - 根據 postfix_func_dict 指定文件後綴調用函數 - 單獨指定讀取某類文件時,直接傳入參數 filename_postfix 便可 支持如下配置文件讀寫 - *.ini ConfigParser - *.yaml yaml TODO 語法等說明 - ConfigParser - yaml # 配置文件使用樣例 ConfigParser https://www.cnblogs.com/klb561/p/10085328.html # *.yaml pyyaml pip install pyyaml """ import os import ConfigParser import sys import traceback import logging import yaml reload(sys) sys.setdefaultencoding("utf-8") # 指定 不一樣後綴調用不一樣方法 postfix_func_dict = { '.ini': 'ini', '.yaml': 'yaml', } # 默認配置後綴 default_filename_postfix = '.ini' ini_config_data = [ {'section': 'scetionA', 'section_vals': [ {'key': '', 'val': '', 'dtype': ''}, {'key': '', 'val': '', 'dtype': ''}, ]} ] ini_config_data = { 'sectionA': { 'key1': 'val1', 'key2': 'val2', }, 'sectionB': { 'key11': 'val11', 'key21': 'val21', }, } from collections import OrderedDict def read_config(config_path, filename_postfix=None): u""" 讀取配置文件 :param str config_path: 配置文件路徑 :param str filename_postfix: 配置文件類型 ini / yaml """ config_data = OrderedDict(dict()) if not config_path or not os.path.exists(config_path): logging.error("配置文件[%s]爲空或不存在", config_path) return config_data filename_postfix = filename_postfix if filename_postfix else os.path.splitext(config_path)[1] # TODO 動態 根據字符串 調用函數 config_data = globals().get('read_config_%s' % postfix_func_dict.get(filename_postfix, default_filename_postfix))( config_path) logging.info("讀取配置文件[%s]成功,配置信息[%s]", config_path, config_data) return config_data def read_config_yaml(config_path): u""" 讀取配置文件 :param str config_path: 配置文件路徑 :return: dict config_data """ # 加上 ,encoding='utf-8',處理配置文件中含中文出現亂碼的狀況。 config_data = OrderedDict(dict()) try: # f = open(config_path, 'r', encoding='utf-8') f = open(config_path, 'r') config = f.read() if float(yaml.__version__) <= 5.1: config_data = yaml.load(config) else: # 5.1版本後 使用 FullLoader 更加安全 config_data = yaml.load(config, Loader=yaml.FullLoader) except Exception as e: logging.error(traceback.format_exc()) logging.error("配置文件[%s]沒法正常解析,請檢查!", config_path) return config_data def read_config_ini(config_path): u""" 讀取配置文件 :param str config_path: 配置文件路徑 :return: dict config_data """ config_data = OrderedDict(dict()) if not config_path or not os.path.exists(config_path): logging.error("配置文件[%s]爲空或不存在", config_path) return config_data try: config = ConfigParser.ConfigParser() config.readfp(open(r'%s' % config_path)) for section in config.sections(): config_data[section] = OrderedDict(dict()) for key, val in config.items(section): config_data[section][key] = val except Exception as e: logging.error(traceback.format_exc()) logging.error("配置文件[%s]沒法正常解析,請檢查!", config_path) return config_data def write_config(config_path, config_data, filename_postfix=None, mode='a', funcname=None): u""" 寫入配置文件 :param str config_path: 配置文件 :param dict config_data: 配置字典 :param str filename_postfix: 配置文件類型 ini / yaml . 爲空時自動讀取文件名稱後綴,根據不一樣後綴調用不一樣函數 :param str mode: 數據時 追加寫入仍是覆蓋等 a w """ filename_postfix = filename_postfix if filename_postfix else os.path.splitext(config_path)[1] mode = mode if mode and mode in ['a', 'w'] else 'a' # TODO 動態 根據字符串 調用函數 config_data = globals().get('write_config_%s' % postfix_func_dict.get(filename_postfix, default_filename_postfix)) \ (config_path, config_data, mode) logging.info("讀取配置文件[%s]成功,配置信息[%s]", config_path, config_data) def write_config_yaml(config_path, config_data, mode): u""" 寫入配置文件 :param str config_path: 配置文件 :param dict config_data: 配置字典 :param str mode: 數據時 追加寫入仍是覆蓋等 a w """ # fw = open(yamlPath, 'a', encoding='utf-8') fw = open(config_path, mode) # a 追加寫入,w,覆蓋寫入 yaml.dump(config_data, fw) return config_data def write_config_ini(config_path, config_data, mode): u""" 寫入配置文件 :param str config_path: 配置文件 :param dict config_data: 配置字典 :param str mode: 數據時 追加寫入仍是覆蓋等 a w """ config = ConfigParser.ConfigParser() if not os.path.exists(config_path): new_config_dic = config_data else: new_config_dic = read_config(config_path) # 當配置文件已經存在時, 將會使用新的dic更新原有配置 if mode == 'a': new_config_dic.update(config_data) for section, section_vals in config_data.items(): config.add_section(section) for key, val in section_vals.items(): config.set(section, key, val) config.write(open(config_path, "w")) logging.info("寫入配置文件[%s]完成", config_path) return config_data if __name__ == '__main__': # yaml config_path = "test.yaml" config_path = "/home/fdm/software/hugegraph/hugegraph-0.9.2/conf/gremlin-server.yaml" config_data = read_config(config_path) write_config('test2.yaml', config_data=config_data, mode='a') exit() # ini config_path = "config.ini" config_data = { 'sectionA': {'a': 'b', 'key1': 123} } write_config('config2.ini', config_data=config_data, mode='a') read_config(config_path)
#! -*- coding:utf-8 u""" Config 讀寫 *.properties 文件 https://www.cnblogs.com/momoyan/p/9145531.html """ import re import os import tempfile from collections import OrderedDict class Properties: def __init__(self, file_name): self.file_name = file_name self.properties = OrderedDict({}) try: fopen = open(self.file_name, 'r') for line in fopen: line = line.strip() if line.find('=') > 0 and not line.startswith('#'): strs = line.split('=') self.properties[strs[0].strip()] = strs[1].strip() except Exception, e: raise e else: fopen.close() def has_key(self, key): return key in self.properties def get(self, key, default_value=''): if key in self.properties: return self.properties[key] return default_value def put(self, key, value): self.properties[key] = value replace_property(self.file_name, key + '=.*', key + '=' + value, True) def parse(file_name): return Properties(file_name) def replace_property(file_name, from_regex, to_str, append_on_not_exists=True): tmpfile = tempfile.TemporaryFile() if os.path.exists(file_name): r_open = open(file_name, 'r') pattern = re.compile(r'' + from_regex) found = None for line in r_open: if pattern.search(line) and not line.strip().startswith('#'): found = True line = re.sub(from_regex, to_str, line) tmpfile.write(line) if not found and append_on_not_exists: tmpfile.write('\n' + to_str) r_open.close() tmpfile.seek(0) content = tmpfile.read() if os.path.exists(file_name): os.remove(file_name) w_open = open(file_name, 'w') w_open.write(content) w_open.close() tmpfile.close() else: print "file %s not found" % file_name if __name__ == '__main__': file_path = 'xxx.properties' props = parse(file_path) #讀取文件 props.put('key_a', 'value_a') #修改/添加key=value print props.get('key_a') #根據key讀取value print "props.has_key('key_a')=" + str(props.has_key('key_a')) #判斷是否包含該key print props.properties()