1

I'm doing a relatively big project for my final thesis and therefore I am using a .ini file for storing and retrieving settings. However, I am unable to find an elegant solution for how to convert the strings (well, actually the strings inside the dictionary) that Configparser returns to numbers (ints and floats) and/or lists.

Googling the issue, I came across this SO thread which only tackles the 'list' part of my problem but using the top rated solution (defining lists inside the .ini file like that: list=item1,item2) didn't do anything for me, as the 'list' still shows up as a string after parsing. Also, I do not want to change format.

So I decided I would try it myself and came up with this solution:

import configparser # create a new instance of a 'ConfigParser' class config = configparser.ConfigParser() # create mock-content for the config file config["Test"] = { "test_string":"string", "test_int":"2", "test_float":"3.0", "test_list":"item1, item2" } # get the relevant settings settings = config["Test"] # pack the relevant settings into a dictionary settings = dict(settings) # iterate through all the key-value pairs and convert them, if possible for key, value in settings.items(): # try to convert to int try: settings[key] = int(value) # if the value can't be converted to int, it might be a float or a list except ValueError: # try converting it to a float try: settings[key] = float(value) # if the value can't be converted to float, try converting to list except ValueError: if "," in value: cont = value.split(",") settings[key] = [item.strip() for item in cont] else: settings[key] = value print(type(settings["test_string"])) print(settings) 

However, this seems so very inelegant and is so heavily nested and the task itself seems so important that I cannot believe that there is no "more official" solution to this that I am simply unable to find.

So, could please someone help me out here and tell me if there really is no better, more straightforward way to achieve this!?

1 Answer 1

2

Best I can do is this (though it's kinda hacky and probably dangerous too):

for key, value in settings.items(): try: # will handle both ints and floats, even tuples with ints/floats settings[key] = eval(value) except NameError: # this means it's a string or a tuple with strings get_val = list(map(str.strip, value.split(","))) settings[key] = get_val if get_val[1:] else get_val[0] 

This will work correctly for ints, floats as well as your comma separated values (it will evaluated it as a tuple, I guess that should be fine though I added a condition for that anyway).

Sign up to request clarification or add additional context in comments.

6 Comments

Thanks for your solution! I'd upvote it but I don't have the 'reputation' yet... But in what way is your solution dangerous, could you please elaborate? And, since I am writing a software for an experiment on a satellite and stability is key here, would you recommend your solution over mine regarding stability or the other way around?
Also, how is it possible that there is no "official" solution for this? I mean it must be an important part of config files to store all kinds of data types or am I doing something wrong here?
Sure, in the try part, the eval basically evaluates your string in an interpreter, so if it's a valid type like int or float, it will pass, it's like when you type 1 or 1.0 in interpreter and you get the same thing back. On the other hand, if you write a string without quotes or with commas, it returns error, hence the except part. Here, it is assumed that the type is string or string with commas, so I split it and return first element (string with no commas split around it will return list of length 1) or the complete list in else case.
By dangerous, I meant using eval which is certainly fine for your case. As to why it is dangerous, you can see this or this.
Wow, that is a lot of information. Thank you very much for helping me out! I'm going to think about what kind of types I am going to need and then decide from there. You have a good... whatever it is you are celebrating next ;)
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.