如何解决configparser.InterpolationMissingOptionError: Bad value substitution以及分析其出现原因

在写配置文档的时候,把logging的formatter格式也进行了ini文档中,如下所示

[Log]
name=test_name
filename=my_log.log
level = INFO
formatter = %(name)s -  %(filename)s  -%(funcName)s   - %(asctime)s  - 日志信息:%(message)s

读取是用的ConfigParser这个类通过read和get去读取,下图是自己封装好的读取配置文件

from configparser import ConfigParser
import os

class MyConfig(ConfigParser):
    def __init__(self):
        """将ConfigParser的初始化方法搬上来,另外通过动态获取方式拿到配置文件的路径,并读取配置文件
        """
        super().__init__()
        dir_log = os.path.dirname(os.path.realpath(__file__))
        path_log = os.path.join(dir_log, "config.ini")
        self.read(path_log,encoding="utf-8")

 在我自己定义的Logger类中使用到上述的这个类,并且用get方法获得文件中的值

class MyLogger(Logger):
    def __init__(self):
        # 获取配置文件的内容
        conf = MyConfig()
        name = conf.get("Log","name")
        file = conf.get("Log","filename")
        level = conf.get("Log","level")
        fmt_str = conf.get("Log","formatter")
        ... # 省略后续,不重要

运行的时候,发现会报一个错误,configparser.InterpolationMissingOptionError: Bad value substitution

configparser.InterpolationMissingOptionError: Bad value substitution:
 option 'formatter' in section 'LOG' contains an interpolation key 'name' 
 which is not a valid option name. Raw value: '%(name)s -  %(filename)s  
 -%(funcName)s   - %(asctime)s  - 日志信息:%(message)s'

 

其实关于configparser,我们可以大胆看一下源码

class ConfigParser(RawConfigParser)

继承自RawConfigParser,相比父类,ConfigParser支持对%(value)s变量的解析

原因是在ConfigParser中有一个私有变量为_DEFAULT_INTERPOLATION

_DEFAULT_INTERPOLATION = BasicInterpolation()

如果interpolation设置为BasicInterpolation(),则配置文件中的%(key)s结构会被解析

同理,指定interpolation参数为ExtendedInterpolation(),那么解析器会解析${section:key}结构

再看一下父类RawConfigParser中_DEFAULT_INTERPOLATION的内容

_DEFAULT_INTERPOLATION = Interpolation()
# RawConfigParser中默认是不对%进行解析的

def __init__(self):
    ....
    if self._interpolation is _UNSET:  
    self._interpolation = self._DEFAULT_INTERPOLATION    
    ...

# 在RawConfigParser类的get方法中,如果raw没有进行传参,默认为False则执行
# self._interpolation.before_get()方法
if raw or value is None:
    return value
else:
    return self._interpolation.before_get(self, section, option, value,
                                          d)        

因此到ini文件中,有类似formatter中格式写入时,又不想格式化,有以下两种操作

# 方法一
# 将读取文件用RawConfigParser类去实例化 (不推荐)
conf = RawConfigParser()
# 方法二
# 继续使用ConfigParser类去实例化然后读取文件,get方法的raw需要关键字传参True
fmt_str = conf.get("Log","formatter",raw=True)

 

 

以上为瓜瓜研究所得,原创博客,请尊重原创

转载请带上本链接,谢谢

 

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值