Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: How to create a dictionary from properties file while omitting comments

I've searched for the answer to this here for awhile and haven't found it, so hope this isn't a dupe.

I have a properties file that mostly contains key=value pairs, but also contains #comments. I need to put it in a dictionary so I can grab values at will. In a file without #comments, the following works perfectly.

myprops = dict(line.strip().split('=') for line in open('/Path/filename.properties'))
print myprops['key']

But not so when there are comments present. If there's #comment present, dictionary says

"ValueError: dictionary update sequence element #x has length 1, 2 is required"

I've tried wrapping the dictionary creation in conditionals with

if not line.startswith('#'):

But I can't seem to get that to work. Suggestions? Thanks!

like image 313
fbonds66 Avatar asked Nov 05 '13 21:11

fbonds66


2 Answers

To address your newest constraint about blank lines, I would try something like:

myprops = {}
with open('filename.properties', 'r') as f:
    for line in f:
        line = line.rstrip() #removes trailing whitespace and '\n' chars

        if "=" not in line: continue #skips blanks and comments w/o =
        if line.startswith("#"): continue #skips comments which contain =

        k, v = line.split("=", 1)
        myprops[k] = v

It's very clear and it's easy to add on extra constraints, whereas using a dict comprehension will get quite bloated. However, you could always format it nicely

myprops = dict(line.strip().split('=') 
               for line in open('/Path/filename.properties'))
               if ("=" in line and 
                   not line.startswith("#") and
                   <extra constraint> and
                   <another extra constraint>))
like image 137
wflynny Avatar answered Nov 11 '22 14:11

wflynny


You should just use the built-in configparser which is made to read ini-style configuration files. It allows comments using ; and # by default, so it should work for you.

For .properties files you might need to trick a bit as the configparser generally expects section names. You can do this easily by adding a dummy section while reading it though:

>>> from configparser import ConfigParser
>>> config = ConfigParser()
>>> with open(r'C:\Users\poke\Desktop\test.properties') as f:
        config.read_string('[config]\n' + f.read())

>>> for k, v in config['config'].items():
        print(k, v)

foo bar
bar baz
baz foo

(Using the same example file as mtitan8)

For Python 2, use from ConfigParser import ConfigParser instead.

like image 29
poke Avatar answered Nov 11 '22 12:11

poke