python模块 configparser--操作文件ini
本文使用的python3.8:https://docs.python.org/zh-cn/3.8/library/configparser.html#module-configparser
1、INI文件
1、ini文件的基本结构
- 配置文件是由小节组成的每个小节都有一个[section]标头,加上多个由特定字符串 (默认为 = 或 : ) 分隔的键/值条目。
- 默认情况下小节名对大小写敏感而键对大小写不敏感。 键和值的开头与末尾的空格会被移除。
- 值可以被省略,在此情况下键/值分隔符也可以被省略。值还可以跨越多行,只要其他行带有比值的第一行更深的缩进。依据解析器的具体模式,空白行可能被视为多行值的组成部分也可能被忽略。
- 配置文件可以包含注释,要带有指定字符前缀 (默认为 # 和 ; )。注释可以单独出现于原本的空白行,并可使用缩进。
示例:
[Simple Values] key=value spaces in keys=allowed spaces in values=allowed as well spaces around the delimiter = obviously you can also use : to delimit keys from values [All Values Are Strings] values like this: 1000000 or this: 3.14159265359 are they treated as numbers? : no integers, floats and booleans are held as: strings can use the API to get converted values directly: true [Multiline Values] chorus: I'm a lumberjack, and I'm okay I sleep all night and I work all day [No Values] key_without_value empty string value here = [You can use comments] # like this ; or this # By default only in an empty line. # Inline comments can be harmful because they prevent users # from using the delimiting characters as parts of values. # That being said, this can be customized. [Sections Can Be Indented] can_values_be_as_well = True does_that_mean_anything_special = False purpose = formatting for readability multiline_values = are handled just fine as long as they are indented deeper than the first line of a value # Did I mention we can indent comments, too?
2、值的插值
- 在核心功能之上ConfigParser还支持插值。这意味着值可以在被get()调用返回之前进行预处理。
1、class configparser.BasicInterpolation(只用引用当前小节的内容)
- 默认实现由 ConfigParser 来使用。它允许值包含引用了相同小节中其他值或者特殊的默认小节中的值的格式字符串。额外的默认值可以在初始化时提供。
-
ConfigParser的interpolation设为BasicInterpolation(),这会将%(home_dir)s求解为home_dir的值(在这里是/Users)。%(my_dir)s的将被实际求解为/Users/lumberjack。所有插值都是按需进行的,这样引用链中使用的键不必以任何特定顺序在配置文件中指明。
当interpolation设为None时,解析器会简单地返回%(my_dir)s/Pictures作为my_pictures的值,并返回%(home_dir)s/lumberjack作为my_dir的值。 - config = configparser.ConfigParser(interpolation=configparser.BasicInterpolation())
示例:
[Paths] home_dir: /Users my_dir: %(home_dir)s/lumberjack my_pictures: %(my_dir)s/Pictures [Escape] gain: 80%% # use a %% to escape the % sign (% is the only character that needs to be escaped)
2、class configparser.ExtendedInterpolation(可以跨小节引用)
- 一个用于插值的替代处理程序实现了更高级的语法,它被用于zc.buildout中的实例。扩展插值使用${section:option}来表示来自外部小节的值。插值可以跨越多个层级。为了方便使用,section:部分可被省略,插值会默认作用于当前小节(可能会从特殊小节获取默认值)。
- config = configparser.ConfigParser(interpolation=configparser.ExtendedInterpolation())
示例1:引用本小节的值
[Paths] home_dir: /Users my_dir: ${home_dir}/lumberjack my_pictures: ${my_dir}/Pictures [Escape] cost: $$80 # use a $$ to escape the $ sign ($ is the only character that needs to be escaped)
示例2:引用其他小节的值
[Common] home_dir: /Users library_dir: /Library system_dir: /System macports_dir: /opt/local [Frameworks] Python: 3.2 path: ${Common:system_dir}/Library/Frameworks/ [Arthur] nickname: Two Sheds last_name: Jackson my_dir: ${Common:home_dir}/twosheds my_pictures: ${my_dir}/Pictures python_dir: ${Frameworks:path}/Python/Versions/${Frameworks:Python}
2、configparser模块:配置文件解析器
1、ConfigParser对象
class configparser.ConfigParser(defaults=None, dict_type=dict, allow_no_value=False, delimiters=('=', ':'), comment_prefixes=('#', ';'), inline_comment_prefixes=None, strict=True, empty_lines_in_values=True, default_section=configparser.DEFAULTSECT, interpolation=BasicInterpolation(), converters={})
- 当给定defaults时,它会被初始化为包含固有默认值的字典。
- 当给定dict_type时,它将被用来创建包含节、节中的选项以及默认值的字典。
- 当allow_no_value为True(默认值:False)时,将接受没有值的选项;此种选项的值将为None并且它们会以不带末尾分隔符的形式被序列化。
- 当给定delimiters时,它会被用作分隔键与值的子字符串的集合。
- 当给定comment_prefixes时,它将被用作在否则为空行的注释的前缀子字符串的集合。注释可以被缩进。
- 当给定inline_comment_prefixes时,它将被用作非空行的注释的前缀子字符串的集合。
- 当strict为True(默认值)时,解析器在从单个源(文件、字符串或字典)读取时将不允许任何节或选项出现重复,否则会引发DuplicateSectionError或DuplicateOptionError。
- 当empty_lines_in_values为False(默认值:True)时,每个空行均表示一个选项的结束。在其他情况下,一个多行选项内部的空行会被保留为值的一部分。
- 当给定default_section时,它将指定存放其他节的默认值和用于插值的特殊节的名称(通常命名为"DEFAULT")。该值可通过使用default_section实例属性在运行时被读取或修改。
- 插值行为可通过给出interpolation参数提供自定义处理程序的方式来定制。None可用来完全禁用插值,ExtendedInterpolation()提供了一种更高级的变体形式,它的设计受到了zc.buildout的启发。
- 当给定converters时,它应当为一个字典,其中每个键代表一个类型转换器的名称而每个值则为实现从字符串到目标数据类型的转换的可调用对象。每个转换器会获得其在解析器对象和节代理上对应的get*()方法。
1、defaults()方法
- 返回包含实例范围内默认值的字典。
2、sections()方法
- 返回可用节的列表;不包括default section。
3、add_section(section)方法
- 向实例添加一个名为section的节。如果给定名称的节已存在,将会引发DuplicateSectionError。如果传入了default section名称,则会引发ValueError。节名称必须为字符串,如果不是则会引发TypeError。
4、has_section(section)方法
- 指明相应名称的section是否存在于配置中。default section不包含在内。
5、options(section)方法
- 返回指定section中可用选项的列表。
6、has_option(section, option)得方法
- 如果给定的section存在并且包含给定的option则返回True;否则返回False。如果指定的section为None或空字符串,则会使用DEFAULT。
7、read(filenames, encoding=None)方法
- 尝试读取并解析一个包含文件名的可迭代对象,返回一个被成功解析的文件名列表。
- 如果filenames为字符串、bytes对象或path-likeobject,它会被当作单个文件来处理。如果filenames中名称对应的某个文件无法被打开,该文件将被忽略。这样的设计使得你可以指定包含多个潜在配置文件位置的可迭代对象(例如当前目录、用户家目录以及某个系统级目录),存在于该可迭代对象中的所有配置文件都将被读取。
- 如果名称对应的文件全都不存在,则ConfigParser实例将包含一个空数据集。一个要求从文件加载初始值的应用应当在调用read()来获取任何可选文件之前使用read_file()来加载所要求的一个或多个文件。
import configparser, os config = configparser.ConfigParser() config.read_file(open('defaults.cfg')) config.read(['site.cfg', os.path.expanduser('~/.myapp.cfg')], encoding='cp1250')
8、read_file(f, source=None)
- 从f中读取并解析配置数据,它必须是一个产生Unicode字符串的可迭代对象(例如以文本模式打开的文件)。
- 可选参数source指定要读取的文件名称。如果未给出并且f具有name属性,则该属性会被用作source;默认值为'<???>'。
9、read_string(string, source='<string>')方法
- 从字符串中解析配置数据。
- 可选参数source指定一个所传入字符串的上下文专属名称。如果未给出,则会使用'<string>'。这通常应为一个文件系统路径或URL。
10、read_dict(dictionary, source='<dict>')
- 从任意一个提供了类似于字典的items()方法的对象加载配置。键为节名称,值为包含节中所出现的键和值的字典。如果所用的字典类型会保留顺序,则节和其中的键将按顺序加入。值会被自动转换为字符串。
- 可选参数source指定一个所传入字曲的上下文专属名称。如果未给出,则会使用<dict>。
- 此方法可被用于在解析器之间拷贝状态。
11、get(section, option, *, raw=False, vars=None[, fallback])方法
- 获取指定名称的section的一个option的值。如果提供了vars,则它必须为一个字典。option的查找顺序为vars*(如果有提供)、*section以及DEFAULTSECT。如果未找到该键并且提供了fallback,则它会被用作回退值。可以提供None作为fallback值。
- 所有'%'插值会在返回值中被展开,除非raw参数为真值。插值键所使用的值会按与选项相同的方式来查找。
12、getint(section, option, *, raw=False, vars=None[, fallback])方法
- 将在指定section中的option强制转换为整数的便捷方法。参见get()获取对于raw,vars和fallback的解释。
13、getfloat(section, option, *, raw=False, vars=None[, fallback])
- 将在指定section中的option强制转换为浮点数的便捷方法。参见get()获取对于raw,vars和fallback的解释。
14、getboolean(section, option, *, raw=False, vars=None[, fallback])方法
- 将在指定section中的option强制转换为布尔值的便捷方法。
- 请注意选项所接受的值为'1','yes','true'和'on',它们会使得此方法返回True,以及'0','no','false'和'off',它们会使得此方法返回False。这些字符串值会以对大小写不敏感的方式被检测。任何其他值都将导致引发ValueError。参见get()获取对于raw,vars和fallback的解释。
15、items(raw=False, vars=None)方法
16、items(section, raw=False, vars=None)方法
- 当未给出section时,将返回由section_name,section_proxy对组成的列表,包括DEFAULTSECT。
- 在其他情况下,将返回给定的section中的option的name,value对组成的列表。可选参数具有与get()方法的参数相同的含义。
- 在3.8版更改:vars中的条目将不在结果中出现。之前的行为混淆了实际的解析器选项和为插值提供的变量。
17、set(section, option, value)方法
- 如果给定的节存在,则将所给出的选项设为指定的值;在其他情况下将引发NoSectionError。option和value必须为字符串;如果不是则将引发TypeError。
18、write(fileobject, space_around_delimiters=True)方法
- 将配置的表示形式写入指定的fileobject,该对象必须以文本模式打开(接受字符串)。此表示形式可由将来的read()调用进行解析。如果space_around_delimiters为真值,键和值之前的分隔符两边将加上空格。
19、remove_option(section, option)方法
- 将指定的option从指定的section中移除。如果指定的节不存在则会引发NoSectionError。如果要移除的选项存在则返回True;在其他情况下将返回False。
20、remove_section(section)方法
- 从配置中移除指定的section。如果指定的节确实存在则返回True。在其他情况下将返回False。
2、查看ini文件
- 默认小节中的值,是所有小节的默认值。即小节中,若无相关选项的,默认值生效。
示例:ini文件示例
[DEFAULT] ServerAliveInterval = 45 Compression = yes CompressionLevel = 9 ForwardX11 = yes [bitbucket.org] User = hg [topsecret.server.com] Port = 50022 ForwardX11 = no
示例:
import configparser config = configparser.ConfigParser() config.read('text.ini') #获取默认小节中各选项键和值,返回字典 print(config.defaults()) #{'serveraliveinterval': '45', 'compression': 'yes', 'compressionlevel': '9', 'forwardx11': 'yes'} #获取文件中各小节名,除默认小节除外 print(config.sections()) #['bitbucket.org', 'topsecret.server.com'] #获取指定小节中各选项的键,包含默认小节的 print(config.options('bitbucket.org')) #['user', 'serveraliveinterval', 'compression', 'compressionlevel', 'forwardx11'] #获取指定小节中各选项键和值,返回由键和值的元组构成的列表 print(config.items('bitbucket.org')) #[('serveraliveinterval', '45'), ('compression', 'yes'), ('compressionlevel', '9'), ('forwardx11', 'yes'), ('user', 'hg')] #判断小节是否存在 print(config.has_section('bitbucket.org')) #True print(config.has_section('bitbucket.con')) #False #判断小节中是否存在选项 print(config.has_option('bitbucket.org', 'user')) #True print(config.has_option('bitbucket.org', 'user1')) #False
3、修改ini文件(修改、添加选项)
- 在各小节中,无法修改默认小节的值。在其他小节中修改默认小节的值,只是在本小节中添加了一个同名的选项。
- 若要修改默认小节,直接指定默认小节即可。
import configparser config = configparser.ConfigParser() config.read('text.ini') print(config.sections()) print(config.items('bitbucket.org')) config.set('bitbucket.org', 'serveraliveinterval', '99') #选项erveraliveinterval是默认小节中的,因此会在bitbucket.org小节中添加该选项 config.set('bitbucket.org', 'user', 'hh') #会在bitbucket.org小节有user选项,因此会直接修改其值 print(config.items('bitbucket.org')) with open('text1.ini', 'w') as file: config.write(file) #执行write之前,上面的修改只是在内存中,没有写入文件中
4、向ini文件中添加小节
import configparser config = configparser.ConfigParser() config.read('text.ini') config.add_section('hengha') #向ini文件中添加一个名为hengha的小节 with open('text.ini', 'w') as file: config.write(file)
5、删除ini文件中的内容
- 在各小节中,无法删除默认小节的值。若小节中有与默认小节同名的选项,该选项被删除后,默认小节的该选项将生效。
- 可以删除默认小节中的选项,但不能删除默认小节。
1、删除选项
import configparser config = configparser.ConfigParser() config.read('text.ini') print(config.sections()) print(config.items('topsecret.server.com')) config.remove_option('topsecret.server.com', 'serveraliveinterval') #serveraliveinterval是默认小节中的选项,因此不能被删除 config.remove_option('topsecret.server.com', 'port') #删除topsecret.server.com小节中的port选项 with open('text1.ini', 'w') as file: config.write(file)
2、删除小节
import configparser config = configparser.ConfigParser() config.read('text.ini') print(config.sections()) config.remove_section('topsecret.server.com') #删除整个topsecret.server.com小节 with open('text1.ini', 'w') as file: config.write(file)
6、支持的数据类型
- 配置解析器并不会猜测配置文件中值的类型,而总是将它们在内部存储为字符串。这意味着如果你需要其他数据类型,你应当自己来转换。
- 配置解析器提供了一系列便捷的获取方法来处理整数、浮点数和布尔值。
- 简单地将值传给bool()是没有用的,bool('False')仍然会是True。为解决这个问题配置解析器还提供了getboolean()。这个方法对大小写不敏感并可识别'yes'/'no','on'/'off','true'/'false'和'1'/'0'等布尔值。
import configparser config = configparser.ConfigParser() config.read('text.ini') print(config.sections()) print(config.items('bitbucket.org')) gethh = config.get('bitbucket.org', 'serveraliveinterval') print(gethh, type(gethh)) #结果是:10 <class 'str'> getinthh = config.getint('bitbucket.org', 'serveraliveinterval') print(getinthh, type(getinthh)) #结果是:10 <class 'int'> getfloathh = config.getfloat('bitbucket.org', 'serveraliveinterval') print(getfloathh, type(getfloathh)) #结果是:10.0 <class 'float'> getbooleanhh = config.getboolean('bitbucket.org', 'compression') print(getbooleanhh, type(getbooleanhh)) #结果是:True <class 'bool'>
7、四种read方式
1、read()的参数是文本文件的路径,即直接读取文件并解析
import configparser config = configparser.ConfigParser() config.read(r'D:\test\python\test\text.ini') #直接打开并解析文件 print(config.sections()) print(config.defaults()) <<< ['bitbucket.org', 'topsecret.server.com'] {'serveraliveinterval': '45', 'compression': 'yes', 'compressionlevel': '9', 'forwardx11': 'yes'}
2、read_file()的参数是打开的文件对象,即读取文件对象并解析
import configparser config = configparser.ConfigParser() with open('text.ini','r') as file: config.read_file(file) #读取文件对象,并解析 print(config.sections()) print(config.defaults()) <<< ['bitbucket.org', 'topsecret.server.com'] {'serveraliveinterval': '45', 'compression': 'yes', 'compressionlevel': '9', 'forwardx11': 'yes'}
3、read_string()的参数是字符串,即读取字符串并解析
import configparser hh=''' [DEFAULT] serveraliveinterval = 45 compression = yes compressionlevel = 9 forwardx11 = yes [bitbucket.org] user = hh serveraliveinterval = 10 [topsecret.server.com] port = 50022 forwardx11 = no ''' config = configparser.ConfigParser() config.read_string(hh) #读取字符串,并解析 print(config.sections()) print(config.defaults()) <<< ['bitbucket.org', 'topsecret.server.com'] {'serveraliveinterval': '45', 'compression': 'yes', 'compressionlevel': '9', 'forwardx11': 'yes'}
4、read_dict()的参数是字典,即读取字典并解析
import configparser dicthh = {'DEFAULT': {'serveraliveinterval': 45, 'compression': 'yes', 'compressionlevel': 9, 'forwardx11': 'yes'}, 'bitbucket.org': {'user': 'hg'}, 'topsecret.server.com': {'port': 50022, 'forwardx11': 'no'}} config = configparser.ConfigParser() config.read_dict(dicthh) #读取字典并解析 print(config.sections()) print(config.defaults()) with open('text1.ini', 'w') as file: config.write(file) <<< ['bitbucket.org', 'topsecret.server.com'] {'serveraliveinterval': '45', 'compression': 'yes', 'compressionlevel': '9', 'forwardx11': 'yes'}