DEAR PEOPLE FROM THE FUTURE: Here's what we've figured out so far...

Welcome! This is a Q&A website for computer programmers and users alike, focused on helping fellow programmers and users. Read more

What are you stuck on? Ask a question and hopefully somebody will be able to help you out!
+1 vote

I have a bunch of configuration files, that are Python files. Files contain only variables, lists, and dictionaries. Would it be possible to read these files from Python, and edit their values in the actual source files? That is, not in memory after they've been loaded, but the actual content of the files on disk.


1 Answer

0 votes

Yes, sure. If you know their location, you can just open them with open(...), modify the contents loaded in a string and then write to the same location.

Else, if you don't want to process the contents of the file as text but you'd rather use Python's own parser, you can use Python's ast.literal_eval() to load the variables in the file, do something with them, serialize them with the pickle module and save them to the same location.


The issue with ast.literal_eval() is that it only takes a single object as input, like a dictionary or a list for example ast.literal_eval('{ "foo": "bar" }'). But in my files I have multiple dictionaries like this

dic1 = { "foo": "bar" }
dic2 = { "bar": "foo" }

I would like to be able for example to read the python file and change the value of dict2["bar"] in the file, on disk, without using text manipulation.

with open("") as file:
    file["dict2"]["bar"] = "xxx"

or something like that, and have the changes written back to the file.

The issue with pickle is that it is a binary format so if I write that it's no longer a Python module.

I think the only way for me is to use another format, JSON or YAML instead of Python files. Too bad because this would have been very convenient for me.


You could load the code with exec, modify the variables, put them inside a tuple and parse the tuple with ast.parse, then use ast.unparse to generate Python code. However, it requires Python 3.9+

Contributions licensed under CC0