每次尝试使用Python中的configparser获取或设置某个节时,如果该节不存在,它将抛出一个NoSectionError。有什么可以避免的吗?此外,在获得选项时,我也可以避免使用NoOptionError吗?
例如,使用字典,有setdefault选项:而不是在键不存在时抛出KeyError,而是添加键,将键的值设置为默认值,并返回默认值。
我目前正在为获取属性执行以下操作:
def read_config(section):
config = configparser.ConfigParser()
config.read(location)
try:
apple = config.get(section, 'apple')
except NoSectionError, NoOptionError:
apple = None
try:
pear = config.get(section, 'pear')
except NoSectionError, NoOptionError:
pear = None
try:
banana = config(section, 'banana')
except NoSectionError, NoOptionError:
banana = None
return apple, pear, banana以下是设置它们的方法:
def save_to_config(section, apple, pear, banana):
config = configparser.ConfigParser()
if not os.path.exists(folder_location):
os.makedirs(folder_location)
config.read(location)
if section not in config.sections():
config.add_section(section)
config.set(section, 'apple', apple)
config.set(section, 'pear', pear)
config.set(section, 'banana', banana)背景不算太糟,因为他们都有相同的部分,但得到是好的.太可怕了。一定有更好的办法。
也许有什么班轮可以让我减少这种情况:
try:
apple = config.get(section, 'apple')
except NoSectionError, NoOptionError:
apple = None对此:
apple = config.get_with_default(section, 'apple', None)-编辑--
我曾尝试根据乐高的建议作出以下修改:
def read_config(section):
defaults = { section : {'apple': None,
'pear': None,
'banana': None }}
config = configparser.ConfigParser(defaults = defaults)
config.read(location)
apple = config.get(section, 'apple')
pear = config.get(section, 'pear')
banana = config(section, 'banana')
return apple, pear, banana但是,如果该节不存在,则仍然会引发NoSectionError。
注意:我也尝试过默认值= {'apple': None, 'pear': None, 'banana': None } (没有部分)
发布于 2014-07-23 17:50:22
另一种办法:
ConfigParser.get提供了一个可以传入的vars参数,如果提供了该参数,它将用作主要查找,但是它会忽略该部分中是否已经存在该选项的值。
因此,我们可以通过ducktyping使用vars,但我们将将.items()的行为更改为:
vars返回默认值。下面是一个非常幼稚的实现:
class DefaultOption(dict):
def __init__(self, config, section, **kv):
self._config = config
self._section = section
dict.__init__(self, **kv)
def items(self):
_items = []
for option in self:
if not self._config.has_option(self._section, option):
_items.append((option, self[option]))
else:
value_in_config = self._config.get(self._section, option)
_items.append((option, value_in_config))
return _items在使用中:
def read_config(section, location):
config = configparser.ConfigParser()
config.read(location)
apple = config.get(section, 'apple',
vars=DefaultOption(config, section, apple=None))
pear = config.get(section, 'pear',
vars=DefaultOption(config, section, pear=None))
banana = config.get(section, 'banana',
vars=DefaultOption(config, section, banana=None))
return apple, pear, banana
def save_to_config(section, location, apple, pear, banana):
config = configparser.ConfigParser()
config.read(location)
if section not in config.sections():
config.add_section(section)
config.set(section, 'apple', apple)
config.set(section, 'pear', pear)
with open(location, 'wb') as cf:
config.write(cf)尽管如此,这是有点间接,但完全正确。
请注意,这仍然会引发NoSectionError。
如果您也试图处理这个问题,ConfigParser.ConfigParser将接受一个dict_type参数,因此您只需使用一个违约实例化该类。
因此,将configparser.ConfigParser()更改为configparser.ConfigParser(dict_type=lambda: defaultdict(list))
对于所有的意图和目的,我可能会使用乐高的建议。
原始问题编辑的更新
如果您想在defaults中使用ConfigParser关键字,那么了解实现是如何定义的可能会有所帮助。下面是如何初始化缺省值的代码。您将看到缺省值的使用与节的使用完全不同。为了更深入地了解他们在get()期间所扮演的角色,请看一下ConfigParser.get()的代码。基本上,如果该部分不是DEFAULTSECT,则抛出一个NoSectionError。
有两种方法可以克服这种情况:
defaultdict想法read_config函数def read_config(section):
defaults = {'apple': None,
'pear': None,
'banana': None }
config = configparser.ConfigParser(defaults = defaults)
config.read(location)
if not config.has_section(section):
config.add_section(section)
apple = config.get(section,'apple')
pear = config.get(section, 'pear')
banana = config.get(section, 'banana')
return apple, pear, banana但我要说的是,由于这不是一条直线,它开辟了更多的路径,比如我提供的DefaultOption类。我们可以把它做得更少一点。
https://stackoverflow.com/questions/24832628
复制相似问题