Search code examples
pythonstring-formattingpython-2.xconfiguration-filesconfigparser

How to store formatted strings in a configuration file?


I am using the ConfigParser module in Python 2.6 and I wish to load formatted strings from my configuration file. An example of such a string might be the following:

[Section Name]
#in the config file
#tmp_string has value 'string'
my_string = 'This is a %s' % tmp_string

Is there a nice way to save such strings in the config file? I am not going to know what the value of the string is until I load the config file, so I can't evaluate it and then save it to the file or anything like that. Obviously at the moment, when I load the string and print it out, I get the following:

#config is the ConfigParser
my_string = config.get('Section Name', 'my_string')
print my_string
>>>'This is a %s' % tmp_string 

I would love to get the output:

>>> This is a string

How do you achieve this? I would preferably like to stay with ConfigParser, but another option may be acceptable. (I know you can't just print the string and have it magically appear how you would like it to, I am just trying to demonstrate what I wish to do.)


Solution

  • If tmp_string is defined in the same section of the config file, then you can reference it in other places in the same section using a special format: %(variable_name)s.

    So applying it to your example:

    myconfig.cfg file

    [Section Name]
    tmp_string = string  ; must be in the same section
    my_string = This is a %(tmp_string)s
    

    Now the value of tmp_string will be "iterpolated" or substituted into the value of my_string when it's retrieved:

    try:
        from ConfigParser import ConfigParser
    except ModuleNotFoundError:
        from configparser import ConfigParser  # Python 3
    
    
    config = ConfigParser()
    print(config.get('Section Name', 'my_string'))
    

    Output:

    This is a string
    

    Note: Normally values outside the current section can't be referenced. However if they were defined in a special section named DEFAULT, their values can be. In other words, the following config file would have produced the same results:

    [DEFAULT]
    tmp_string = string
    
    [Section Name]
    my_string = This is a %(tmp_string)s
    

    If a name is defined in both the DEFAULT section and in the same section as a reference to it, the "local" value in the same section takes precedence and will be the one used.

    Python 3 Changes

    The ConfigParser module was renamed configparser and an alternative handler for interpolation which implements a more advanced syntax is available via a new ExtendedInterpolation class which added. To enable its use you would need to create an instance of it and use it when instantiating the ConfigParser class — which can be done very succinctly by doing both at once like this:

    config = configparser.ConfigParser(interpolation=configparser.ExtendedInterpolation())
    

    This form of interpolation accept strings with the format: ${section:variable_name}. Aside from being slightly more readable than %(variable_name)s, the looked-up variable can be in any specified section, not just a special one named DEFAULT. If the section: part is left out, the variable name must be in the current section (or the special DEFAULT section if there is one).