python INI文件操作与configparser内置库

简介: python INI文件操作与configparser内置库

image.png

INI文件

即Initialization File的缩写,是Windows系统配置文件所采用的存储格式,用于统管Windows的各项配置。虽然Windows 95之后引入了注册表的概念,使得许多参数和初始化信息被存储在注册表中,但在某些场合,INI文件仍然具有其不可替代的地位。


INI文件是一种按照特殊方式排列的文本文件,其格式规范包括节(section)、键(name)和值(value)。节用方括号括起来,单独占一行,用于表示一个段落,区分不同用途的参数区。键(也称为属性)单独占一行,用等号连接键名和键值,例如“name=value”。注释使用英文分号(;)开头,单独占一行,分号后面的文字直到该行结尾都作为注释处理。


INI文件在Windows系统中非常常见,其中最重要的是“System.ini”、“System32.ini”和“Win.ini”等文件。这些文件主要存放用户所做的选择以及系统的各种参数。用户可以通过修改INI文件来改变应用程序和系统的很多配置。当然,我们自己编写程序时也可以把INI文件作为配置和管理参数的工具,比如python中就有内置库configparser可以方便地配置和管理程序的参数。


configparser内置库

类与方法

   Intrinsic defaults can be specified by passing them into the ConfigParser constructor as a dictionary.


   class:


   ConfigParser -- responsible for parsing a list of configuration files, and managing the parsed database.


       methods:


       __init__(defaults=None, dict_type=_default_dict, allow_no_value=False,

                delimiters=('=', ':'), comment_prefixes=('#', ';'),

                inline_comment_prefixes=None, strict=True,

                empty_lines_in_values=True, default_section='DEFAULT',

                interpolation=<unset>, converters=<unset>):


           Create the parser. When `defaults` is given, it is initialized into the dictionary or intrinsic defaults. The keys must be strings, the values must be appropriate for %()s string interpolation.


           When `dict_type` is given, it will be used to create the dictionary objects for the list of sections, for the options within a section, and for the default values.


           When `delimiters` is given, it will be used as the set of substrings that divide keys from values.


           When `comment_prefixes` is given, it will be used as the set of substrings that prefix comments in empty lines. Comments can be indented.


           When `inline_comment_prefixes` is given, it will be used as the set of substrings that prefix comments in non-empty lines.


           When `strict` is True, the parser won't allow for any section or option

           duplicates while reading from a single source (file, string or

           dictionary). Default is True.


           When `empty_lines_in_values` is False (default: True), each empty line marks the end of an option. Otherwise, internal empty lines of a multiline option are kept as part of the value.


           When `allow_no_value` is True (default: False), options without values are accepted; the value presented for these is None.


           When `default_section` is given, the name of the special section is named accordingly. By default it is called ``"DEFAULT"`` but this can be customized to point to any other valid section name. Its current value can be retrieved using the ``parser_instance.default_section`` attribute and may be modified at runtime.


           When `interpolation` is given, it should be an Interpolation subclass instance. It will be used as the handler for option value pre-processing when using getters. RawConfigParser objects don't do any sort of interpolation, whereas ConfigParser uses an instance of BasicInterpolation. The library also provides a ``zc.buildout`` inspired ExtendedInterpolation implementation.


           When `converters` is given, it should be a dictionary where each key represents the name of a type converter and each value is a callable implementing the conversion from string to the desired datatype. Every converter gets its corresponding get*() method on the parser object and section proxies.


       sections()

           Return all the configuration section names, sans DEFAULT.


       has_section(section)

           Return whether the given section exists.


       has_option(section, option)

           Return whether the given option exists in the given section.


       options(section)

           Return list of configuration options for the named section.


       read(filenames, encoding=None)

           Read and parse the iterable of named configuration files, given by name.  A single filename is also allowed.  Non-existing files are ignored.  Return list of successfully read files.


       read_file(f, filename=None)

           Read and parse one configuration file, given as a file object.

           The filename defaults to f.name; it is only used in error messages (if f has no `name` attribute, the string `<???>` is used).


       read_string(string)

           Read configuration from a given string.


       read_dict(dictionary)

           Read configuration from a dictionary. Keys are section names, values are dictionaries with keys and values that should be present in the section. If the used dictionary type preserves order, sections and their keys will be added in order. Values are automatically converted to strings.


       get(section, option, raw=False, vars=None, fallback=_UNSET)

           Return a string value for the named option.  All % interpolations are expanded in the return values, based on the defaults passed into the constructor and the DEFAULT section.  Additional substitutions may be provided using the `vars` argument, which must be a dictionary whose contents override any pre-existing defaults. If `option` is a key in `vars`, the value from `vars` is used.


       getint(section, options, raw=False, vars=None, fallback=_UNSET)

           Like get(), but convert value to an integer.


       getfloat(section, options, raw=False, vars=None, fallback=_UNSET)

           Like get(), but convert value to a float.


       getboolean(section, options, raw=False, vars=None, fallback=_UNSET)

           Like get(), but convert value to a boolean (currently case insensitively defined as 0, false, no, off for False, and 1, true, yes, on for True).  Returns False or True.


       items(section=_UNSET, raw=False, vars=None)

           If section is given, return a list of tuples with (name, value) for each option in the section. Otherwise, return a list of tuples with (section_name, section_proxy) for each section, including DEFAULTSECT.


       remove_section(section)

           Remove the given file section and all its options.


       remove_option(section, option)

           Remove the given option from the given section.


       set(section, option, value)

           Set the given option.


       write(fp, space_around_delimiters=True)

           Write the configuration state in .ini format. If `space_around_delimiters` is True (the default), delimiters between keys and values are surrounded by spaces.


操作实例

就以我电脑上的win.ini的内容作操作对象,为防止乱改windows参数,把win.ini复制到源代码目录中并改名为exam.ini。


; for 16-bit app support
[fonts]
[extensions]
[mci extensions]
[files]
[Mail]
MAPI=1


导入INI文件

>>> import configparser

>>> parser = configparser.ConfigParser()

>>> parser.read('exam.ini')

['exam.ini']


可以同时读取多个文件,以文件列表作参数


>>> parser.read(['exam.ini', 'exam1.ini'])

['exam.ini', 'exam1.ini']

>>> parser.read(['exam.ini', 'exam2.ini'])

['exam.ini']

>>> parser.read(['exam2.ini'])

[]


注意:文件不存在并不报错,只是没有对应的返回值。


另一种形式:parser.read_file(file)


>>> with open('exam.ini', 'r') as file:  

...     parser.read_file(file)


主要区别:


parser.read() 是基于文件名的,它打开文件并读取内容。而 parser.read_file() 则接受一个已经打开的文件对象。

parser.read() 可以接受多个文件名,而 parser.read_file() 一次只能处理一个文件对象。

使用 parser.read_file() 时,你需要自己处理文件的打开和关闭。而 parser.read() 则会在内部处理这些操作。

查询所有节的列表

>>> parser.sections()

['fonts', 'extensions', 'mci extensions', 'files', 'Mail']


判断某个节是否存在

>>> parser.has_section('fonts')
True
>>> parser.has_section('font')
False
>>> parser.has_section('files')
True


查询某个节的所有键的列表

>>> parser.options('Mail')
['mapi']
>>> parser.options('mail')
Traceback (most recent call last):
  File "<pyshell#21>", line 1, in <module>
    parser.options('mail')
  File "D:\Program Files\Python\Lib\configparser.py", line 661, in options
    raise NoSectionError(section) from None
configparser.NoSectionError: No section: 'mail'
>>> parser.options('files')
[]
>>> parser.options('Files')
Traceback (most recent call last):
  File "<pyshell#31>", line 1, in <module>
    parser.options('Files')
  File "D:\Program Files\Python\Lib\configparser.py", line 661, in options
    raise NoSectionError(section) from None
configparser.NoSectionError: No section: 'Files'


注意:节名区别字母大小写。


判断节下是否存在某个键

>>> parser.has_option('Mail','mapi')
True
>>> parser.has_option('Mail','Mapi')
True
>>> parser.has_option('Mail','MAPI')
True
>>> parser.has_option('Mail','abc')
False
>>> parser.has_option('Mail','ABC')
False
注意:键名不区别字母大小写。


增加节点

>>> parser.add_section('Names')
>>> parser.sections()
['fonts', 'extensions', 'mci extensions', 'files', 'Mail', 'Names']
>>> parser.add_section('names')
>>> parser.sections()
['fonts', 'extensions', 'mci extensions', 'files', 'Mail', 'Names', 'names']
注意:增加已在节,会抛错DuplicateSectionError(section)
>>> parser.add_section('names')
Traceback (most recent call last):
  File "<pyshell#47>", line 1, in <module>
    parser.add_section('names')
  File "D:\Program Files\Python\Lib\configparser.py", line 1189, in add_section
    super().add_section(section)
  File "D:\Program Files\Python\Lib\configparser.py", line 645, in add_section
    raise DuplicateSectionError(section)
configparser.DuplicateSectionError: Section 'names' already exists
正确用法,配合has_section()一起使用
>>> if not parser.has_section('Level'):
...     parser.add_section('Level')
... 
>>> parser.sections()
['fonts', 'extensions', 'files', 'Mail', 'names', 'Level']


删除节点

>>> parser.sections()
['fonts', 'extensions', 'mci extensions', 'files', 'Mail', 'Names', 'names']
>>> parser.remove_section('Names')
True
>>> parser.remove_section('file')
False
>>> parser.remove_section('mci extensions')
True
>>> parser.sections()
['fonts', 'extensions', 'files', 'Mail', 'names']


注意:是否删除成功,由返回值True或False来判断。


增加节点的键

>>> parser.options('Mail')

['mapi']

>>> if not parser.has_option("Mail", "names"):

...     parser.set("Mail", "names", "")

...

...    

>>> parser.options('Mail')

['mapi', 'names']


修改键值

与增加键一样用set(),但value参数不为空。


>>> parser.set("Mail", "names", "Hann")


或者写成:


parser.set(section="Mail", option="names", value="Hann")


保存修改结果

>>> parser.write(fp=open('exam.ini', 'w'))


注意:增删等改变ini文件内容的操作都要write才能得到保存。


获取键值

>>> parser.get("Mail", "names")

'Hann'

>>> parser.get("Mail", "Names")

'Hann'

>>> parser.get("mail", "Names")

Traceback (most recent call last):

 File "<pyshell#81>", line 1, in <module>

   parser.get("mail", "Names")

 File "D:\Program Files\Python\Lib\configparser.py", line 759, in get

   d = self._unify_values(section, vars)

 File "D:\Program Files\Python\Lib\configparser.py", line 1130, in _unify_values

   raise NoSectionError(section) from None

configparser.NoSectionError: No section: 'mail'


注意:再次证明节名区别大小写,键名不区别大小写。


获取键值时指定值的类型:getint,getfloat,getboolean


>>> parser.getint("Mail", "mAPI")

1

>>> parser.getfloat("Mail", "mapi")

1.0

>>> parser.getboolean("Mail", "mapi")

True


注意:一但所取值不能转为指定类型会报ValueError错误。


错:    return conv(self.get(section, option, **kwargs))

ValueError: invalid literal for int() with base 10: 'Tom'

或:    return conv(self.get(section, option, **kwargs))

ValueError: could not convert string to float: 'Tom'

或:    raise ValueError('Not a boolean: %s' % value)

ValueError: Not a boolean: Tom


获取节点所有键值

>>> parser.items('Mail')

[('mapi', '1'), ('name', '"Hann"'), ('names', 'Tom'), ('kates', '')]


其他读取方式

configparser的读取除了read和read_file从文件中读取还能从字串或字典中读取。


从字串中读取 read_string

字串的内容要与ini文件格式一样才能正常读取:

import configparser
config_string = """  
[DEFAULT]  
Name = Hann Yang
CodeAge = 16
[User]  
Username = boysoft2002
 
[CSDN HomePage]  
Url = https://blog.csdn.net/boysoft2002
Rank = 110
Blogs = 999
Visits = 3300000
VIP = True
Expert = True
"""  
parser = configparser.ConfigParser()  
parser.read_string(config_string)  
print(parser.get('CSDN HomePage', 'Url'))
print(parser.get('CSDN HomePage', 'Expert'))


从字典中读取 read_dict

嵌套字典的格式也要与ini格式匹配才能正常读取:

import configparser
config_dict = {
    'DEFAULT': {
        'Name': 'Hann Yang',
        'CodeAge': 16
    },
    'User': {
        'Username': 'boysoft2002'
    },  
    'CSDN HomePage': {
        'Url': 'https://blog.csdn.net/boysoft2002',
        'Rank': 110,
        'Visits': 3300000,
        'VIP': True,
        'Expert': True
    }
}
 
parser = configparser.ConfigParser()
parser.read_dict(config_dict)
print(parser.get('CSDN HomePage', 'Url'))
print(parser.get('CSDN HomePage', 'Expert'))


完整示例代码

import configparser  
 
# 创建一个配置解析器  
parser = configparser.ConfigParser()  
 
# 读取INI文件  
parser.read('exam.ini')  
 
# 检查是否成功读取了文件  
if len(parser.sections()) == 0:  
    print("INI文件为空或未找到指定的节。")  
else:  
    # 获取所有节的列表  
    sections = parser.sections()  
    print("INI文件中的节:")  
    for section in sections:  
        print(section)  
 
    # 获取指定节下的所有选项  
    section_name = 'Mail'
    if section_name in parser:  
        options = parser[section_name]  
        print(f"节 '{section_name}' 中的选项:")  
        for option in options:  
            print(f"{option}: {parser[section_name][option]}")  
 
        # 获取指定节下的单个选项的值  
        option_name = 'Name'  # 假设我们要获取的选项的名字是 'example_option'  
        if option_name in options:  
            value = parser.get(section_name, option_name)  
            print(f"节 '{section_name}' 中 '{option_name}' 的值为:{value}")  
 
        # 修改指定节下的单个选项的值  
        new_value = 'Name'  
        parser.set(section_name, option_name, new_value)  
        print(f"已将节 '{section_name}' 中 '{option_name}' 的值修改为:{new_value}")  
 
        # 添加一个新的选项到指定节  
        new_option_name = 'new_option'  
        new_option_value = 'option_value'  
        parser.set(section_name, new_option_name, new_option_value)  
        print(f"已在节 '{section_name}' 中添加了新选项 '{new_option_name}',其值为:{new_option_value}")  
 
        # 删除指定节下的单个选项  
        parser.remove_option(section_name, new_option_name)  
        print(f"已删除节 '{section_name}' 中的选项 '{new_option_name}'")  
 
        # 添加一个新的节  
        new_section_name = 'new_section'  
        parser.add_section(new_section_name)  
        print(f"已添加新节 '{new_section_name}'")  
 
        # 将修改后的配置写回文件  
        with open('exam.ini', 'w') as configfile:  
            parser.write(configfile)  
        print("修改已写回INI文件。")  
    else:  
        print(f"INI文件中未找到节 '{section_name}'。")


目录
相关文章
|
1月前
|
存储 人工智能 测试技术
如何使用LangChain的Python库结合DeepSeek进行多轮次对话?
本文介绍如何使用LangChain结合DeepSeek实现多轮对话,测开人员可借此自动生成测试用例,提升自动化测试效率。
298 125
如何使用LangChain的Python库结合DeepSeek进行多轮次对话?
|
1月前
|
监控 数据可视化 数据挖掘
Python Rich库使用指南:打造更美观的命令行应用
Rich库是Python的终端美化利器,支持彩色文本、智能表格、动态进度条和语法高亮,大幅提升命令行应用的可视化效果与用户体验。
113 0
|
3月前
|
存储 Web App开发 前端开发
Python + Requests库爬取动态Ajax分页数据
Python + Requests库爬取动态Ajax分页数据
|
14天前
|
数据可视化 关系型数据库 MySQL
【可视化大屏】全流程讲解用python的pyecharts库实现拖拽可视化大屏的背后原理,简单粗暴!
本文详解基于Python的电影TOP250数据可视化大屏开发全流程,涵盖爬虫、数据存储、分析及可视化。使用requests+BeautifulSoup爬取数据,pandas存入MySQL,pyecharts实现柱状图、饼图、词云图、散点图等多种图表,并通过Page组件拖拽布局组合成大屏,支持多种主题切换,附完整源码与视频讲解。
98 4
【可视化大屏】全流程讲解用python的pyecharts库实现拖拽可视化大屏的背后原理,简单粗暴!
|
22天前
|
传感器 运维 前端开发
Python离群值检测实战:使用distfit库实现基于分布拟合的异常检测
本文解析异常(anomaly)与新颖性(novelty)检测的本质差异,结合distfit库演示基于概率密度拟合的单变量无监督异常检测方法,涵盖全局、上下文与集体离群值识别,助力构建高可解释性模型。
216 10
Python离群值检测实战:使用distfit库实现基于分布拟合的异常检测
|
2月前
|
运维 Linux 开发者
Linux系统中使用Python的ping3库进行网络连通性测试
以上步骤展示了如何利用 Python 的 `ping3` 库来检测网络连通性,并且提供了基本错误处理方法以确保程序能够优雅地处理各种意外情形。通过简洁明快、易读易懂、实操性强等特点使得该方法非常适合开发者或系统管理员快速集成至自动化工具链之内进行日常运维任务之需求满足。
155 18
|
2月前
|
机器学习/深度学习 API 异构计算
JAX快速上手:从NumPy到GPU加速的Python高性能计算库入门教程
JAX是Google开发的高性能数值计算库,旨在解决NumPy在现代计算需求下的局限性。它不仅兼容NumPy的API,还引入了自动微分、GPU/TPU加速和即时编译(JIT)等关键功能,显著提升了计算效率。JAX适用于机器学习、科学模拟等需要大规模计算和梯度优化的场景,为Python在高性能计算领域开辟了新路径。
234 0
JAX快速上手:从NumPy到GPU加速的Python高性能计算库入门教程
|
2月前
|
数据采集 存储 Web App开发
Python爬虫库性能与选型实战指南:从需求到落地的全链路解析
本文深入解析Python爬虫库的性能与选型策略,涵盖需求分析、技术评估与实战案例,助你构建高效稳定的数据采集系统。
288 0
|
2月前
|
存储 监控 安全
Python剪贴板监控实战:clipboard-monitor库的深度解析与扩展应用
本文介绍了基于Python的剪贴板监控技术,结合clipboard-monitor库实现高效、安全的数据追踪。内容涵盖技术选型、核心功能开发、性能优化及实战应用,适用于安全审计、自动化办公等场景,助力提升数据管理效率与安全性。
129 0

推荐镜像

更多