72

I have a config file abc.txt which looks somewhat like:

path1 = "D:\test1\first"
path2 = "D:\test2\second"
path3 = "D:\test2\third"

I want to read these paths from the abc.txt to use it in my program to avoid hard coding.

a4aravind
  • 1,202
  • 1
  • 14
  • 25
  • 3
    Inventing your own formats, even if they look simple like that, is not the best idea generally. Better stick to a builtin one, there are plenty of choices: .ini, json, yaml, xml... – georg Oct 15 '13 at 11:31
  • 1
    Related : [What's the best practice using a settings file in Python?](http://stackoverflow.com/questions/5055042/) – Skippy le Grand Gourou Jan 24 '17 at 11:19
  • 1
    Also see [Config files in Python](https://tutswiki.com/read-write-config-files-in-python/) – Chankey Pathak Oct 08 '20 at 02:14

7 Answers7

121

In order to use my example, your file "abc.txt" needs to look like this.

[your-config]
path1 = "D:\test1\first"
path2 = "D:\test2\second"
path3 = "D:\test2\third"

Then in your code you can use the config parser.

import ConfigParser

configParser = ConfigParser.RawConfigParser()   
configFilePath = r'c:\abc.txt'
configParser.read(configFilePath)

As human.js noted in his comment, in Python 3, ConfigParser has been renamed configparser. See Python 3 ImportError: No module named 'ConfigParser' for more details.

apaderno
  • 28,547
  • 16
  • 75
  • 90
Kobi K
  • 7,743
  • 6
  • 42
  • 86
  • I've edited the post, my suggestion is for using config files it much easier and very useful, that way you can learn a new thing that can really help you. the error `MissingSectionHeaderError` was beacuse you need the section `[file]` – Kobi K Oct 15 '13 at 10:54
  • Certainly useful; did not know this before. +1 – tobias_k Oct 15 '13 at 10:56
  • Hi @Kobi, I'm having one doubt as well. I put my "abc.txt" inside the project folder and I do not want to give the absolute path here [configFilePath = r'c:\abc.txt']. Instead, I want only the absolute path to be assigned to the configFilePath so that even if I move my script to other machines, I don't have to change the path here containing the project workspace location, etc. Is there anyway to accomplish that ? – a4aravind Oct 16 '13 at 04:42
  • @user2882117 you are right that you want to use relative path (that's the correct name) instead of absolute path you can find a good solution in here [here](http://stackoverflow.com/a/7166139/1982962) – Kobi K Oct 16 '13 at 06:52
  • Thanks, but it's yielding me [error] NameError ( name '__file__' is not defined ) and in my previous comment I had a typo, actually I meant "Instead, I want only the relative path to be assigned to the..." – a4aravind Oct 16 '13 at 07:10
  • 2
    @KobiK I'm able to get the path of the currently executed script file by os.path.abspath(os.path.dirname(sys.argv[0])). Then I could do an os.path.join with my "abc.txt". That solved the issue. Thanks a lot – a4aravind Oct 16 '13 at 09:29
  • NP:) that's a nice approach. – Kobi K Oct 17 '13 at 15:16
  • 7
    in python 3, ConfigParser is renamed to configparser. Check here for details http://stackoverflow.com/questions/14087598/python-3-importerror-no-module-named-configparser – human.js Aug 16 '16 at 15:53
  • it's better to call the file abc.ini – STF Nov 09 '17 at 09:34
  • Great answer so +1. I wish the Python team would make up their minds as regards capitalisation! – Adam893 Jan 23 '18 at 13:55
  • 2
    You may want to remove quotes from your config file variables content since using configParser.get('your-config', 'path1') will add another stack of (single) quotes (tested on python3 configparser) – Brown nightingale Jun 13 '19 at 23:42
  • Hello, we are using configparser() to parse the config values in the code but the changes we make to the config.ini is not getting reflected. We have built the executable of our python app and along with the config.ini next to it. But it looks like it packaged the config.ini within the exe and not referencing the config file and its changes. how to handle that? – Ak777 Jul 14 '23 at 22:00
38

You need a section in your file:

[My Section]
path1 = D:\test1\first
path2 = D:\test2\second
path3 = D:\test2\third

Then, read the properties:

import ConfigParser

config = ConfigParser.ConfigParser()
config.readfp(open(r'abc.txt'))
path1 = config.get('My Section', 'path1')
path2 = config.get('My Section', 'path2')
path3 = config.get('My Section', 'path3')
user278064
  • 9,982
  • 1
  • 33
  • 46
24

If you need to read all values from a section in properties file in a simple manner:

Your config.cfg file layout :

[SECTION_NAME]  
key1 = value1  
key2 = value2  

You code:

   import configparser

   config = configparser.RawConfigParser()
   config.read('path_to_config.cfg file')
    
   details_dict = dict(config.items('SECTION_NAME'))

This will give you a dictionary where keys are same as in config file and their corresponding values.

details_dict is :

{'key1':'value1', 'key2':'value2'}

Now to get key1's value : details_dict['key1']

Putting it all in a method which reads sections from config file only once(the first time the method is called during a program run).

def get_config_dict():
    if not hasattr(get_config_dict, 'config_dict'):
        get_config_dict.config_dict = dict(config.items('SECTION_NAME'))
    return get_config_dict.config_dict

Now call the above function and get the required key's value :

config_details = get_config_dict()
key_1_value = config_details['key1'] 


Generic Multi Section approach:

[SECTION_NAME_1]  
key1 = value1  
key2 = value2  

[SECTION_NAME_2]  
key1 = value1  
key2 = value2

Extending the approach mentioned above, reading section by section automatically and then accessing by section name followed by key name.

def get_config_section():
    if not hasattr(get_config_section, 'section_dict'):
        get_config_section.section_dict = collections.defaultdict()
        
        for section in config.sections():
            get_config_section.section_dict[section] = dict(config.items(section))
    
    return get_config_section.section_dict

To access:

config_dict = get_config_section()

port = config_dict['DB']['port'] 

(here 'DB' is a section name in config file and 'port' is a key under section 'DB'.)

MANU
  • 1,358
  • 1
  • 16
  • 29
5

A convenient solution in your case would be to include the configs in a yaml file named **your_config_name.yml** which would look like this:

path1: "D:\test1\first"
path2: "D:\test2\second"
path3: "D:\test2\third"

In your python code you can then load the config params into a dictionary by doing this:

import yaml
with open('your_config_name.yml') as stream:
    config = yaml.safe_load(stream)

You then access e.g. path1 like this from your dictionary config:

config['path1']

To import yaml you first have to install the package as such: pip install pyyaml into your chosen virtual environment.

kjoeter
  • 151
  • 3
  • 3
3

This looks like valid Python code, so if the file is on your project's classpath (and not in some other directory or in arbitrary places) one way would be just to rename the file to "abc.py" and import it as a module, using import abc. You can even update the values using the reload function later. Then access the values as abc.path1 etc.

Of course, this can be dangerous in case the file contains other code that will be executed. I would not use it in any real, professional project, but for a small script or in interactive mode this seems to be the simplest solution.

Just put the abc.py into the same directory as your script, or the directory where you open the interactive shell, and do import abc or from abc import *.

tobias_k
  • 81,265
  • 12
  • 120
  • 179
  • 1
    Thanks, but I don't have a project build and all. I'm just running the Python script from commandline only. Is it possible to do something like this in this case ? I mean is there any other way to make these together as a package or something like that ? – a4aravind Oct 15 '13 at 11:01
  • @user2882117 Sure, just put the `abc.py` in the same directory as your script, or the directory you start an interactive shell in, and do `import abc`. Particularly if it's just for a small script, I think this is the simplest solution, but I would not use it in a "real" project. – tobias_k Oct 15 '13 at 11:08
  • You need to be careful with backslashes in strings. – Alex Che Aug 22 '18 at 17:26
3

For Pyhon 3.X:

Notice the lowercase import configparser makes a big difference.

Step 1:

Create a file called "config.txt" and paste the below two lines:

 [global]
 mykey = prod/v1/install/
    

Step 2:

Go to the same directory and create a testit.py and paste the code below into a file and run it. (FYI: you can put the config file anywhere you like you, you just have to change the read path)

#!/usr/bin/env python
import configparser

config = configparser.ConfigParser()
config.read(r'config.txt')   

print(config.get('global', 'mykey') )
grepit
  • 21,260
  • 6
  • 105
  • 81
0

Since your config file is a normal text file, just read it using the open function:

file = open("abc.txt", 'r')
content = file.read()
paths = content.split("\n") #split it into lines
for path in paths:
    print path.split(" = ")[1]

This will print your paths. You can also store them using dictionaries or lists.

path_list = []
path_dict = {}
for path in paths:
    p = path.split(" = ")
    path_list.append(p)[1]
    path_dict[p[0]] = p[1]

More on reading/writing file here. Hope this helps!

aIKid
  • 26,968
  • 4
  • 39
  • 65