Python configparser:获取未使用项的列表

2024-06-28 20:00:26 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用Python的configparser读取ini文件。你知道吗

在解析之后,我想打印一个没有被解析器使用的条目列表,以通知用户他们已经在ini文件中添加了将被忽略的条目。你知道吗

考虑这样一个ini文件:

[DEFAULT]
param1 = 1
param2 = 2
param3 = 3
param4 = 4

我想要的是:

parser = configparser.ConfigParser()
parser.read(config_path)    
p1 = parser["DEFAULT"]["param1"]
p2 = parser["DEFAULT"]["param2"]
unused = parser["DEFAULT"].get_unused_keys()

最后一行是编成的。我希望变量“unused”包含

["param3", "param4"]

我在手册中没有发现有提到这样的功能,但我会发现它非常有用。我可以从ConfigParser继承并扩展所有访问函数,使其具有跟踪是否访问了特定项的标志,但我希望有一种更简单的方法。你知道吗


Tags: 文件用户defaultparser解析器列表unused条目
2条回答

我已经写了一个解决方案。它不太优雅,但很管用。您需要从RawConfigParser类创建子类,并在类中创建dict变量并扩展get, _get方法。如下所示,当您使用get, getint, getfloat, getboolean方法获取variable的值时,相关方法会将节和变量附加到dict中。当您调用get_unused_keys方法时,它会用已经使用的选项过滤节中所有可用的选项,并给出未使用的选项。你知道吗

完整代码:

try:
    import ConfigParser as Cp
except ImportError:
    import configparser as Cp


class ConfigParser(Cp.RawConfigParser):
    """
    ConfigParser class contains the all ConfigParser related implementations.
    """

    used_vars = {}

    def get_unused_keys(self, section):
        all_sections = self.options(section)
        unused_options = [x for x in all_sections if x not in self.used_vars[section]]
        return unused_options

    def get(self, section, option, *, raw=False, vars=None, fallback=Cp._UNSET):
        if section not in self.used_vars:
            self.used_vars[section] = [option]
        else:
            self.used_vars[section].append(option)
        return super().get(section, option, raw=raw, vars=vars, fallback=fallback)

    def _get(self, section, conv, option, **kwargs):
        if section not in self.used_vars:
            self.used_vars[section] = [option]
        else:
            self.used_vars[section].append(option)
        return super()._get(section, conv, option, **kwargs)


parser = ConfigParser()
parser.read("test.ini")

p1 = parser.getint(section="TEST", option="param1")
print("TEST section - param1 = {}".format(p1))
p2 = parser.getboolean(section="TEST", option="param2")
print("TEST section - param2 = {}".format(p2))
print("Unused options in 'TEST' section: {}".format(parser.get_unused_keys("TEST")))
print("")
par2 = parser.get(section="TEST_SEC", option="param2")
print("TEST_SEC section - param2 = {}".format(par2))
print("Unused options in 'TEST_SEC' section: {}".format(parser.get_unused_keys("TEST_SEC")))

使用的ini文件:

[TEST]
param1 = 1
param2 = True
param3 = 3
param4 = False

[TEST_SEC]
param1 = 89
param2 = Hello World
param3 = 655

输出:

>>> python3 test.py 
TEST section - param1 = 1
TEST section - param2 = True
Unused options in 'TEST' section: ['param3', 'param4']

TEST_SEC section - param2 = Hello World
Unused options in 'TEST_SEC' section: ['param1', 'param3']

仅供参考:

您不应该使用DEFAULT作为节的名称,因为它是一个特殊的节,您可能会得到意外的行为。我已经在实现中添加了_get方法。如果您检查ConfigParser的原始实现,您可以看到所有特定于类型的getter都使用此方法,因此可以对其进行更改。这意味着现在实现也支持getint, getfloat, getboolean方法。 我希望我的回答对你有帮助!你知道吗

对允许的键进行set。然后创建一个set的已用键。从使用过的键中减去alllowed键。你知道吗

In [1]: import configparser                                                                              

In [2]: config = configparser.ConfigParser()                                                             
Out[2]: <configparser.ConfigParser at 0x80a0624d0>

In [3]: config.read_string("""[DEFAULT] 
   ...: param1 = 1 
   ...: param2 = 2 
   ...: param3 = 3 
   ...: param4 = 4""")                                                                                   

In [4]: allowed_keys = {'param1', 'param2'}                                                              
Out[4]: {'param1', 'param2'}

In [5]: usedkeys = set(config['DEFAULT'].keys())                                                         
Out[5]: {'param1', 'param2', 'param3', 'param4'}

In [6]: illegal_keys = usedkeys - allowed_keys                                                           
Out[6]: {'param3', 'param4'}

使用相同的技术,您可以拥有允许的节名称,以及只允许在某些节中使用的参数。你知道吗

例如,您可以将allowed_keys变成dictset

In [7]: allowed_keys = {'DEFAULT': {'param1', 'param2'}, 'section1': {'param3', 'param4'}}               
Out[7]: {'DEFAULT': {'param1', 'param2'}, 'section1': {'param3', 'param4'}}

因此,您可以首先查看节名称,然后查看允许节的允许参数名称。你知道吗

相关问题 更多 >