如何用Python3读写INI文件?
- 2025-03-04 08:27:00
- admin 原创
- 70
问题描述:
我需要使用 Python3读取、写入和创建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!!' )
更新文件.INI
default_path = "var/shared/"
default_file = "file.txt"
default_message = "Hey! help me!!"
解决方案 1:
可以从以下几点开始:
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)
您可以在官方 configparser 文档中找到更多内容。
解决方案 2:
这是一个完整的读取、更新和写入示例。
输入文件,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
原始输入文件保持不变。
解决方案 3:
http://docs.python.org/library/configparser.html
在这种情况下,Python 的标准库可能会有所帮助。
解决方案 4:
标准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'
解决方案 5:
我的backup_settings.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
解决方案 6:
ConfigObj是 ConfigParser 的一个很好的替代品,它提供了更多的灵活性:
嵌套部分(子部分),任意级别
列表值
多行值
字符串插值(替换)
集成强大的验证系统,包括自动类型检查/转换重复部分并允许默认值
在写出配置文件时,ConfigObj 会保留所有注释以及成员和部分的顺序
许多用于处理配置文件的有用方法和选项(例如“重新加载”方法)
全面支持 Unicode
但它有一些缺点:
您无法设置分隔符,它必须是
=
...(拉取请求)您不能有空值,当然可以,但是它们看起来像:
fuabr =
而不是fubar
看起来奇怪和错误。
解决方案 7:
您可以使用python-benedict
,它是一个 dict 子类,为大多数常见格式提供规范化 I/O 支持,包括ini
。
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)
它经过了充分的测试和记录,请查看自述文件来查看所有功能:
文档:https://github.com/fabiocaccamo/python-benedict
安装:pip install python-benedict
注:我是这个项目的作者
解决方案 8:
我在使用 configparser 时发现了一些问题,例如 - 当我尝试从 param 获取值时出现错误:
目标=\my-server\backup$%用户名%
因为解析器无法通过特殊字符 '%' 获取该值。于是,我基于 '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 + '
')
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)
解决方案 9:
使用嵌套字典。看一下:
INI 文件: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("
")
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"
解决方案 10:
如果像问题中一样,你既没有章节标题也没有任何嵌套,那么这个简单的一行程序将为你创建一个字典:
with open("/etc/os-release", "rt") as f:
conf = dict((lambda l: (l[0], l[2][:-1].strip('"')))(line.partition("="))
for line in f)
{
"SUPPORT_URL": "https://help.ubuntu.com/",
"UBUNTU_CODENAME": "noble",
"PRIVACY_POLICY_URL":
"https://www.ubuntu.com/legal/terms-and-policies/privacy-policy",
"NAME": "Ubuntu",
"VERSION_CODENAME": "noble",
"ID_LIKE": "debian",
"VERSION_ID": "24.04",
"BUG_REPORT_URL": "https://bugs.launchpad.net/ubuntu/",
"PRETTY_NAME": "Ubuntu Noble Numbat (development branch)",
"VERSION": "24.04 (Noble Numbat)",
"LOGO": "ubuntu-logo",
"HOME_URL": "https://www.ubuntu.com/",
"ID": "ubuntu"
}
(如果您想要conf.ID
而不是conf["ID"]
;,您可以使用class
;构建type
一个,或者尝试namedtuple
或 - 如果您将支持限制为 Python 3.7+ - dataclasses
)
扫码咨询,免费领取项目管理大礼包!