如何用 Python 3读写 INI 文件?

我需要用 Python 3读取、写入和创建一个 INI文件。

文件 INI

default_path = "/path/name/"
default_file = "file.txt"

Python 文件:

#    Read file and and create if it not exists
config = iniFile( 'FILE.INI' )


#    Get "default_path"
config.default_path


#    Print (string)/path/name
print config.default_path


#    Create or Update
config.append( 'default_path', 'var/shared/' )
config.append( 'default_message', 'Hey! help me!!' )

更新 FILE.INI

default_path    = "var/shared/"
default_file    = "file.txt"
default_message = "Hey! help me!!"
300560 次浏览

Http://docs.python.org/library/configparser.html

在这种情况下,Python 的标准库可能会有所帮助。

这可以从以下几点开始:

import configparser


config = configparser.ConfigParser()
config.read('FILE.INI')
print(config['DEFAULT']['path'])     # -> "/path/name/"
config['DEFAULT']['path'] = '/var/shared/'    # update
config['DEFAULT']['default_message'] = 'Hey! help me!!'   # create


with open('FILE.INI', 'w') as configfile:    # save
config.write(configfile)

你可以在 正式的配置解析器文档找到更多。

下面是一个完整的读、更新和写示例。

输入文件 test.ini

[section_a]
string_val = hello
bool_val = false
int_val = 11
pi_val = 3.14

工作代码。

try:
from configparser import ConfigParser
except ImportError:
from ConfigParser import ConfigParser  # ver. < 3.0


# instantiate
config = ConfigParser()


# parse existing file
config.read('test.ini')


# read values from a section
string_val = config.get('section_a', 'string_val')
bool_val = config.getboolean('section_a', 'bool_val')
int_val = config.getint('section_a', 'int_val')
float_val = config.getfloat('section_a', 'pi_val')


# update existing value
config.set('section_a', 'string_val', 'world')


# add a new section and some values
config.add_section('section_b')
config.set('section_b', 'meal_val', 'spam')
config.set('section_b', 'not_found_val', '404')


# save to a file
with open('test_update.ini', 'w') as configfile:
config.write(configfile)

输出文件 test _ update. ini

[section_a]
string_val = world
bool_val = false
int_val = 11
pi_val = 3.14


[section_b]
meal_val = spam
not_found_val = 404

原始输入文件保持不变。

标准的 ConfigParser通常需要通过 config['section_name']['key']访问,这并不好玩。稍微修改一下就可以提供属性访问:

class AttrDict(dict):
def __init__(self, *args, **kwargs):
super(AttrDict, self).__init__(*args, **kwargs)
self.__dict__ = self

AttrDict 是一个派生自 dict的类,它允许通过字典键和属性访问: 这意味着 a.x is a['x']

我们可以在 ConfigParser中使用这个类:

config = configparser.ConfigParser(dict_type=AttrDict)
config.read('application.ini')

现在我们有了 application.ini:

[general]
key = value

作为

>>> config._sections.general.key
'value'

ConfigObj 是 ConfigParser 的一个很好的替代品,它提供了更大的灵活性:

  • 嵌套部分(小节) ,到任何级别
  • 列出值
  • 多行值
  • 字符串插值(替换)
  • 集成了一个强大的验证系统,包括自动类型检查/转换重复部分,并允许默认值
  • 在写出配置文件时,ConfigObj 保留所有注释以及成员和节的顺序
  • 许多用于处理配置文件的有用方法和选项(如“ reload”方法)
  • 完全支持 Unicode

它有一些缺点:

  • 您不能设置分隔符,它必须是 =... (撤回请求)
  • 你不能有空值,你可以,但他们看起来喜欢: fuabr =而不仅仅是 fubar看起来怪异和错误。

我的 Back _ sets. ini 备份 _ 设置文件中的内容

[Settings]
year = 2020

用于读取的 python 代码

import configparser
config = configparser.ConfigParser()
config.read('backup_settings.ini') #path of your .ini file
year = config.get("Settings","year")
print(year)

用于书写或更新

from pathlib import Path
import configparser
myfile = Path('backup_settings.ini')  #Path of your .ini file
config.read(myfile)
config.set('Settings', 'year','2050') #Updating existing entry
config.set('Settings', 'day','sunday') #Writing new entry
config.write(myfile.open("w"))

输出

[Settings]
year = 2050
day = sunday

在使用配置解析器时,我发现了一些问题,比如——当我试图从 param 获取值时,出现了一个错误:

目的地 = my-server 备份 $% USERNAME%

这是因为解析器无法获取具有特殊字符“%”的值。然后我编写了一个解析器,用于读取基于‘ re’模块的 ini 文件:

import re


# read from ini file.
def ini_read(ini_file, key):
value = None
with open(ini_file, 'r') as f:
for line in f:
match = re.match(r'^ *' + key + ' *= *.*$', line, re.M | re.I)
if match:
value = match.group()
value = re.sub(r'^ *' + key + ' *= *', '', value)
break
return value




# read value for a key 'destination' from 'c:/myconfig.ini'
my_value_1 = ini_read('c:/myconfig.ini', 'destination')


# read value for a key 'create_destination_folder' from 'c:/myconfig.ini'
my_value_2 = ini_read('c:/myconfig.ini', 'create_destination_folder')




# write to an ini file.
def ini_write(ini_file, key, value, add_new=False):
line_number = 0
match_found = False
with open(ini_file, 'r') as f:
lines = f.read().splitlines()
for line in lines:
if re.match(r'^ *' + key + ' *= *.*$', line, re.M | re.I):
match_found = True
break
line_number += 1
if match_found:
lines[line_number] = key + ' = ' + value
with open(ini_file, 'w') as f:
for line in lines:
f.write(line + '\n')
return True
elif add_new:
with open(ini_file, 'a') as f:
f.write(key + ' = ' + value)
return True
return False




# change a value for a key 'destination'.
ini_write('my_config.ini', 'destination', '//server/backups$/%USERNAME%')


# change a value for a key 'create_destination_folder'
ini_write('my_config.ini', 'create_destination_folder', 'True')


# to add a new key, we need to use 'add_new=True' option.
ini_write('my_config.ini', 'extra_new_param', 'True', True)

使用嵌套字典:

文件: example.INI

[Section]
Key = Value

密码:

class IniOpen:
def __init__(self, file):
self.parse = {}
self.file = file
self.open = open(file, "r")
self.f_read = self.open.read()
split_content = self.f_read.split("\n")


section = ""
pairs = ""


for i in range(len(split_content)):
if split_content[i].find("[") != -1:
section = split_content[i]
section = string_between(section, "[", "]")  # define your own function
self.parse.update({section: {}})
elif split_content[i].find("[") == -1 and split_content[i].find("="):
pairs = split_content[i]
split_pairs = pairs.split("=")
key = split_pairs[0].trim()
value = split_pairs[1].trim()
self.parse[section].update({key: value})


def read(self, section, key):
try:
return self.parse[section][key]
except KeyError:
return "Sepcified Key Not Found!"


def write(self, section, key, value):
if self.parse.get(section) is  None:
self.parse.update({section: {}})
elif self.parse.get(section) is not None:
if self.parse[section].get(key) is None:
self.parse[section].update({key: value})
elif self.parse[section].get(key) is not None:
return "Content Already Exists"

这样应用代码:

ini_file = IniOpen("example.ini")
print(ini_file.parse) # prints the entire nested dictionary
print(ini_file.read("Section", "Key") # >> Returns Value
ini_file.write("NewSection", "NewKey", "New Value"

您可以使用 python-benedict,它是一个 dict 子类,为大多数常见格式(包括 ini)提供规范化的 I/O 支持。

from benedict import benedict


# path can be a ini string, a filepath or a remote url
path = 'path/to/config.ini'


d = benedict.from_ini(path)


# do stuff with your dict
# ...


# write it back to disk
d.to_ini(filepath=path)

它经过了良好的测试和文档化,检查 README 以查看所有特性:

文件: https://github.com/fabiocaccamo/python-benedict

安装: pip install python-benedict

注意: 我是这个项目的作者