语言学习练手必备之文件读写,就来处理下ini文件吧。
ini格式(http://zh.wikipedia.org/wiki/INI%E6%A0%BC%E5%BC%8F)
[section1]
; some comment on section1
var1 = foo
var2 = doodle
[section2]
# some comment on section2
var1 = baz
var2 = shoodle
[section3]
var1 = bar # blabla
var2 = ; default
实现了一个IniFileParser类进行读写、查找、修改,还没有添加功能。
#! /usr/bin/env python
# -*- coding: utf-8 -*-
import re
import string
NoSectionException = 'NoSectionException'
NoOptionException = 'NoOptionException'
class IniFileParser:
def __init__(self):
self.sections = {}
def read(self, filename):
try:
f = open(filename, 'r')
except:
return ('Cannot open this file!\n')
for line in f:
# removing whitespace
line = line.strip()
if line == "":
continue
# skiping comments
if line[0] == '#' or line[0] == ';':
continue
# sections
if line[0] == '[':
line = line.strip('[]')
options = {}
self.sections[line] = options
# options
else:
# Assuming that no comments follow
key, value = line.split('=', 1)
key = key.strip()
value = value.strip()
options[key] = value
f.close()
def sections(self):
return self.sections.keys()
def has_section(self, section):
return section in self.sections.keys()
def options(self, section):
if not self.has_section(section):
return None
return self.sections[section].keys()
def has_option(self, section, option):
return self.sections[section].has_key(option)
def get(self, section, option):
if not self.has_section(section):
return None
if not self.has_option(section, option):
return None
return self.sections[section][option]
def set(self, section, option, value):
if not self.has_section(section): raise NoSectionException
if not self.has_option(section, option): raise NoOptionException
self.sections[section][option] = value
def write(self, filename):
# automatically close the file
with open(filename, 'w') as f:
for s in self.sections:
section = '\n[' + s + ']\n'
f.write(section)
for o in self.sections[s]:
option = o + '=' + self.sections[s][o] + '\n'
f.write(option)
可以注意到,上面的代码是无法处理(name, value)参数对后面所跟的注释语句的,因为这里只是简单地对行首字符进行判断。那么更好的实现方法,当然是使用正则表达式。在论坛找到一个参考:
match_section = re.compile(r'^\[([\w\s\.]*)\]$').match(line)
if match_section: # section name line
line = match_section.group(1) # get section name
sec_keys = dict()
self.section_obj[line] = sec_keys
else: # key=value line
re_comment = re.compile(r'[;#].*')
line = re_comment.sub('', line) # remove comments in line
[key, value] = map(string.strip, line.split('=', 1))
sec_keys[key] = value