26

I have a config file as follows:

[job]
mailto=bob
logFile=blahDeBlah.txt

I want to read the options using SafeConfigParser:

values = {} 
config = ConfigParser.SafeConfigParser()
try:
    config.read(configFile)
    jobSection = 'job'

    values['mailto'] = config.get( jobSection, 'mailto' )
    values['logFile'] = config.get( jobSection, 'logFile' )
    # it is not there
    values['nothingThere'] = config.get( jobSection, 'nothingThere' )
.... # rest of code

The last line of course will throw an error. How can I specify a default value for the config.get() method?

Then again, if I have an options file as follows:

[job1]
mailto=bob
logFile=blahDeBlah.txt

[job2]
mailto=bob
logFile=blahDeBlah.txt

There seems to be no way to specify default options for job1 different from the default options in section job2.

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Martlark
  • 14,208
  • 13
  • 83
  • 99

4 Answers4

23

Use the defaults parameter to the constructor:

# class ConfigParser.SafeConfigParser([defaults[, dict_type]]) 
#
config = ConfigParser.SafeConfigParser({'nothingThere': 'lalalalala'})
...
...
# If the job section has no "nothingThere", "lalalalala" will be returned
# 
config.get(jobSection, 'nothingThere')
Eli Bendersky
  • 263,248
  • 89
  • 350
  • 412
  • 13
    Todah, I was confused that there seems to be no way to specify the [section] name for the default. I'll try it today. – Martlark May 24 '11 at 22:28
  • 12
    I do not understand how this answers the question. What if defaults should be different for job1 and job2? – CPBL Mar 07 '16 at 15:35
  • This won't actually work because "nothingThere" automatically gets lowercased to "nothingthere". If you want option names to be case-sensitive you need to do config.optionxform=str, then config.set('DEFAULT', 'nothingThere', 'lalalalala') – timidpueo Dec 09 '16 at 22:48
22

You can also use a default ".ini" file and read it before your actual config file.

default.ini:

[job1]
mailto=jack
logfile=default.log

[job2]
mailto=john
logfile=default.log

config.ini:

[job1]
mailto=sparrow
logfile=blah.log

[job2]
logfile=blah2.log

parsing:

import ConfigParser  # For Python 3 use the configparser module instead (all lowercase)

config = ConfigParser.SafeConfigParser()
config.read('default.ini')
config.read('config.ini')

print config.get('job1', 'mailto')
# -> sparrow (from config.ini)

print config.get('job1', 'logfile')
# -> blah.log (from config.ini)

print config.get('job2', 'mailto')
# -> john (from default.ini)

print config.get('job2', 'logfile')
# -> blah2.log (from config.ini)
Wenuka
  • 887
  • 2
  • 9
  • 25
Manokha
  • 269
  • 2
  • 4
  • I think this is the best answer to the OP question – Luke101 Jun 06 '18 at 17:50
  • @Luke101 it's kind of awkward when distributing a package though. You have to distribute the default.ini in the package data and jump through some hoops to read it back when you need it. – Ben Farmer Jan 25 '23 at 00:17
  • @Ben Farmer - In that case you can embed your default ini inside the program as a multiline string and replace `config.read('default.ini')` with `config.read_string(mydefaultstring)` – Chris Maurer Aug 30 '23 at 20:02
18

In Python 3 you can provide a fallback value to the get() method as follows:

values['nothingThere'] = config.get('job', 'nothingThere', fallback=0)
print(values['nothingThere'])
# -> 0
Andy White
  • 408
  • 4
  • 6
  • 1
    The default value is already provided by the second argument, and I have never seen a `fallback` argument. Can you point to some documentation? – Mad Physicist Apr 26 '17 at 13:48
  • 1
    Note that this is the parser-level get method, not the section's get method, hence the second argument is the key, not a default value. Documentation here - https://docs.python.org/3/library/configparser.html#fallback-values – Andy White Apr 26 '17 at 15:25
  • @MadPhysicist It depends how you use the ConfigParser. You can either call it with `config["my_section"].get("my_option", "fallback_value")` (and here, indeed the second argument "fallback_value" will be the default value) or with `config.get("my_section", "my_option", fallback="fallback_value")` (and here the two first arguments are to specify which option of which section you want to get) – Florentin Le Moal Feb 27 '18 at 10:21
  • This is exactly what I want. Thanks. – EsmaeelE Feb 16 '21 at 13:53
11

You can use the [DEFAULT] section to set default values for the properties you haven't defined in any other section(s).

E.g.

[DEFAULT]
checkout_root: /data/workspace

[pingpong]
name: Ping Pong App
checkout_root: /home/pingpong
src: %(checkout_root)s/src

[dingdong]
name: Ding Dong App
src: %(checkout_root)s/dingdong_src

For the ding ding app, the value of src will be /data/workspace/dingdong_src

Niels Bom
  • 8,728
  • 11
  • 46
  • 62
Kaushalya
  • 1,009
  • 1
  • 10
  • 10