python 关于读取ini文件的 ConfigParser 随笔 保留注释 大小写敏感
[toc]
简单说一下
工作需要 需要批量修改很多机器上的配置文件,当然,只需要修改一行
配置文件格式为ini 每台机器上的配置文件都不一样,但是一定会有自己需要的那一行
这个时候,肯定会有很多人说,”这不简单吗,readline然后再判断是否包含,然后在修改就行了“
是的,问题的确就是这样做的话未免有些不雅观,都用python,那肯定要找一找有没有读取修改ini这种配置文件的python的库,最好还是python自带的,否则装库也麻烦
假设要修改的ini
[TEST1]
;; 这是注释
TEST_OPT_1 = 1
;; 这也是一处注释
TEST_OPT_2 = dotest
OPT_PATH = /home/auser
[LISTEN]
;; 只监听本机ip
BIND_IP = 127.0.0.1
;; 监听端口
BIND_PORT = 80
MAX_FDS = 102400
SWITCH_USER = webserver
需要修改LISTEN节的BIND_PORT这个item,将其改为BIND_IP = 8080
库 ConfigParser
服务器是2.6.6 本地是2.7.x 具体忘了,但也正因此埋下了坑 坑后面说
import ConfigParser
import os
import shutil
try:
from collections import OrderedDict as _default_dict
except ImportError:
# fallback for setup.py which hasn't yet built _collections
_default_dict = dict
class myconf(ConfigParser.ConfigParser):
def __init__(self, defaults=None, dict_type=_default_dict,
allow_no_value=False):
ConfigParserLib.ConfigParser.__init__(self,defaults, dict_type,
allow_no_value)
# 这里重写了optionxform方法,直接返回选项名
def optionxform(self, optionstr):
return optionstr
def replaceText(path,aim,replace):
lines = open(path).readlines()
fp = open(path,'w')
for s in lines:
fp.write( s.replace(aim,replace))
fp.close()
currPath = os.path.dirname(os.path.realpath(__file__))
configPath = os.path.join(currPath,"file/test.ini")
backConfigPath = os.path.join(currPath,"file/test.ini.bak")
shutil.copyfile(configPath,backConfigPath)
g_aim = ";"
g_replace = "@"
replaceText(configPath,g_aim,g_replace)
config = myconf()
config.read(configPath)
config.set('LISTEN',"BIND_PORT","8080")
config.write(open(configPath,"w"))
replaceText(configPath,g_replace,g_aim)
print "success"
这是我的替换代码
版本差异 tip
避免了很多的坑 ,但还是出问题了 服务器环境2.6.6 ConfigParser
没有allow_no_value
这个属性,起作用是解析无意义的符号
慢慢来缕一缕
保存为小写问题
有人会发现 我是将ConfigParser
重载了来使用的,其中,我重载了optionxform方法,因为原本的这个方法是这样的
def optionxform(self, optionstr):
return optionstr.lower()
为了体现读取配置ini时候的大小写不敏感,python再读取对应内容的时候,都将其小写了,无论本来的内容是大写的也好,小写的也罢,都会变成小写的
于是 你使用这个玩意读取出来再存回去的配置全都会变成小写的,简直离谱
保留注释
接着 我自定义了一个replaceText
方法,为什么要用替换方法来替换原本文件的内容呢?
替换的目标是;
替换成@
;
是ini之中的注释,因为程序是不读取注释的,没错,通过这个库,你重新生成的配置是没有一丝丝注释的——我感觉我拿脚本把所有的配置文件都跑一遍的话,会被骂死~
于是我就开始搜寻,发现需要先把注释替换为别的字符,然后开启allow_no_value=True
默认值是False,这样 程序就会读取注释了,再在生成的内容中将@
替换为;
,我们的注释就保留成功了
真 版本差异问题探讨
前面说了 版本问题很重要
那么该怎么办呢?
个人做法---把2.7的库掏出来
在2.6的python下 用我捞出来的库 当然,记得改名称,不然就导标准库去了