5

I have a config file with some options defined. Sometimes, if the requested option is not found, I want to ignore the error and return None.

setting.cfg:

[Set]
ip=some_ip
verify=yes     #if verify does not exist here --> verify=None

test.py:

import sys
import ConfigParser

file="setting.cfg"

class ReadFile:
   def read_cfg_file(self):
      configParser = ConfigParser.RawConfigParser(allow_no_value=True)
      if os.path.isfile(file):
          configParser.read(file)
      else:
          sys.exit(1)
      try:
          verify = configParser.get('Set', 'verify')
      except ConfigParser.NoOptionError:
          pass

      return verify,and,lots,of,other,values

If I handle it like this, I can't return values, as it simply passes if the 'verify' option is not found.

Is there any way I can ignore errors if an option is not found, and instead return None?

For example, something like this:

verify = configParser.get('Set', 'verify')
if not verify:
    verify=False
Kevin J. Chase
  • 3,856
  • 4
  • 21
  • 43
Dave
  • 221
  • 2
  • 12

3 Answers3

5

Python 3's configparser module is much-improved and provides a get(option, default) method.

Python 2's ConfigParsers allow for a DEFAULT section (supplied at construction time) although in that case you would have to know the defaults for each option ahead of time.

If you are on Python 2 and need to provide a default at the call site, sub-classing per Rob's answer seems like the way to go.

Sam Brightman
  • 2,831
  • 4
  • 36
  • 38
  • 2
    Py3 method works well for me. Just note that to get a `get` method that behaves like the one for a `dict` you need a `configparser` **section** not the parser itself. Eg. `parser = ConfigParser(); parser.read('settings.ini'); section = parser['SECTION']; section.get('option', 'default')`. If you use the parser directly, you need to be more explicit: `parser.get('SECTION', 'option', fallback='default')`. See https://docs.python.org/3/library/configparser.html#fallback-values for details. – Heath Raftery Apr 15 '22 at 05:27
3

If it were me, I'd derive a new config parser class from RawConfigParser, adding in only the new special behavior, like so:

from ConfigParser import RawConfigParser, NoOptionError
from StringIO import StringIO
from collections import defaultdict

class MyConfigParser(RawConfigParser):
    def get(self, section, option):
        try:
            return RawConfigParser.get(self, section, option)
        except NoOptionError:
            return None


settings=StringIO('''
[Set]
ip=192.0.2.76
verify=yes
[Set2]
ip=192.0.2.74
''')

cfg=MyConfigParser(allow_no_value=True)
cfg.readfp(settings)

assert cfg.get('Set', 'verify') ==  'yes'
assert cfg.get('Set2', 'verify') == None
Robᵩ
  • 163,533
  • 20
  • 239
  • 308
1

Python 2.7.12

You can take advantage of the ConfigParser() class get() method, which allows you to specify a defaults dictionary when called:

$ cat myconf.txt
[files]
path1 = /tmp
path2 = /usr/bin
path3 =

$ ipython
...
In [1]: import ConfigParser
   ...: 
   ...: cp = ConfigParser.ConfigParser(allow_no_value=True)
   ...: cp.read('myconf.txt')
   ...: defaults = { 'path4' : '/opt/include'}
   ...: print 'path1:', cp.get('files', 'path1', 0, defaults)
   ...: print 'path3:', cp.get('files', 'path3', 0, defaults)
   ...: print 'path4:', cp.get('files', 'path4', 0, defaults)
   ...: 
path1: /tmp
path3: 
path4: /opt/include
PJ_Finnegan
  • 1,981
  • 1
  • 20
  • 17