如何使用Python3读取和写入INI文件?

如何使用Python3读取和写入INI文件?,python,python-3.x,ini,Python,Python 3.x,Ini,我需要用Python3读取、写入和创建一个INI文件 FILE.INI default_path = "/path/name/" default_file = "file.txt" default_path = "var/shared/" default_file = "file.txt" default_message = "Hey! help me!!" Python文件: # Read file and and create if it not exists conf

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

FILE.INI

default_path = "/path/name/"
default_file = "file.txt"
default_path    = "var/shared/"
default_file    = "file.txt"
default_message = "Hey! help me!!"
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 = "/path/name/"
default_file = "file.txt"
default_path    = "var/shared/"
default_file    = "file.txt"
default_message = "Hey! help me!!"


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)

原始输入文件保持不变。

标准的
ConfigParser
通常需要通过
config['section\u name']['key']
进行访问,这并不有趣。稍加修改即可提供属性访问:

class AttrDict(dict):
    def __init__(self, *args, **kwargs):
        super(AttrDict, self).__init__(*args, **kwargs)
        self.__dict__ = self
是从
dict
派生的类,它允许通过字典键和属性访问进行访问:这意味着
a.x是一个['x']

我们可以在
ConfigParser
中使用此类:

config = configparser.ConfigParser(dict_type=AttrDict)
config.read('application.ini')
现在我们通过以下方式获得
application.ini

[general]
key = value
作为

是ConfigParser的良好替代品,它提供了更大的灵活性:

  • 嵌套节(子节),任何级别
  • 列表值
  • 多行值
  • 字符串插值(替换)
  • 与功能强大的验证系统集成,包括自动类型检查/转换重复部分,并允许默认值
  • 写入配置文件时,ConfigObj保留所有注释以及成员和节的顺序
  • 许多使用配置文件的有用方法和选项(如“重新加载”方法)
  • 完全支持Unicode
它有一些倒退:

  • 您不能设置分隔符,它必须是
    =
    …()
  • 你不能有空值,当然可以,但它们看起来像:
    fuabr=
    ,而不仅仅是
    fubar
    ,这看起来既奇怪又错误
我的备份设置.ini文件中的内容

用于阅读的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

使用configparser时,我发现了一些问题,例如-我尝试从param获取值时出错:

目标=\my server\backup$%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)

使用嵌套字典。看一看:

INI文件:example.INI

[Section]
Key = Value
代码:

应用如下代码:

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支持

从benedict导入benedict
#路径可以是ini字符串、文件路径或远程url
path='path/to/config.ini'
d=本尼迪克特(路径)
#用你的口授做些事情
# ...
#将其写回磁盘
d、 至_ini(文件路径=路径)
它经过了良好的测试和记录,请查看自述文件以查看所有功能:

文件:

安装:
pip安装python benedict


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

怎么样?事实上,怎么样?一个合适的ini文件需要一个像
[foobar]
这样的节标题。另请参见好的技巧,但是这个方法的用户应该注意,当访问像
配置这样的文件时。\u sections.general.key=“3”
这不会更改配置选项的内部值,因此只能用于只读访问。如果在执行
.read()
命令后,配置被扩展或更改(添加选项,某些节的值对,->进行插值,这可能非常重要),则不应使用此访问方法!此外,对
config.\u节[“节”][“选择”]
的任何访问都是私有的,它会绕过插值并返回原始值!Sardathrion是正确的,如果您希望在文件中保留注释,并且在原始文件中保留节顺序,ConfigObj是一种方法。ConfigParser只会清除您的注释,并在某些时候扰乱顺序。当使用提供的示例文件而没有正确的节标题时,找不到对多行列表的支持,例如长文件名给定
ConfigParser.MissingSectionHeaderError
。在我的Python 3.7系统上,行“config.set('section_b'、'not_found_val',404)”必须更改为“config.set('section_b'、'not_found_val',str(404)),因为“set”的参数必须是字符串。非常好的示例,谢谢!看起来
read
方法现在返回读取文件的列表,但不返回内容
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"