在 ConfigParser 中保存 case? ?

我尝试使用 Python 的 ConfigParser模块来保存设置。对于我的应用程序来说,在我的章节中保留每个名字的大小写是很重要的。文档中提到将 str ()传递给 Optionxform ()可以完成这个任务,但是对我来说不起作用。名字都是小写的。我错过了什么吗?

<~/.myrc contents>
[rules]
Monkey = foo
Ferret = baz

我得到的 Python 伪代码:

import ConfigParser,os


def get_config():
config = ConfigParser.ConfigParser()
config.optionxform(str())
try:
config.read(os.path.expanduser('~/.myrc'))
return config
except Exception, e:
log.error(e)


c = get_config()
print c.options('rules')
[('monkey', 'foo'), ('ferret', 'baz')]
42185 次浏览

The documentation is confusing. What they mean is this:

import ConfigParser, os
def get_config():
config = ConfigParser.ConfigParser()
config.optionxform=str
try:
config.read(os.path.expanduser('~/.myrc'))
return config
except Exception, e:
log.error(e)


c = get_config()
print c.options('rules')

I.e. override optionxform, instead of calling it; overriding can be done in a subclass or in the instance. When overriding, set it to a function (rather than the result of calling a function).

I have now reported this as a bug, and it has since been fixed.

I know this question is answered, but I thought some people might find this solution useful. This is a class that can easily replace the existing ConfigParser class.

Edited to incorporate @OozeMeister's suggestion:

class CaseConfigParser(ConfigParser):
def optionxform(self, optionstr):
return optionstr

Usage is the same as normal ConfigParser.

parser = CaseConfigParser()
parser.read(something)

This is so you avoid having to set optionxform every time you make a new ConfigParser, which is kind of tedious.

For me worked to set optionxform immediately after creating the object

config = ConfigParser.RawConfigParser()
config.optionxform = str

Caveat:

If you use defaults with ConfigParser, i.e.:

config = ConfigParser.SafeConfigParser({'FOO_BAZ': 'bar'})

and then try to make the parser case-sensitive by using this:

config.optionxform = str

all your options from config file(s) will keep their case, but FOO_BAZ will be converted to lowercase.

To have defaults also keep their case, use subclassing like in @icedtrees answer:

class CaseConfigParser(ConfigParser.SafeConfigParser):
def optionxform(self, optionstr):
return optionstr


config = CaseConfigParser({'FOO_BAZ': 'bar'})

Now FOO_BAZ will keep it's case and you won't have InterpolationMissingOptionError.

Add to your code:

config.optionxform = lambda option: option  # preserve case for letters