Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Python, how do I tie an on-disk JSON file to an in-process dictionary?

In perl there was this idea of the tie operator, where writing to or modifying a variable can run arbitrary code (such as updating some underlying Berkeley database file). I'm quite sure there is this concept of overloading in python too.

I'm interested to know what the most idiomatic way is to basically consider a local JSON file as the canonical source of needed hierarchical information throughout the running of a python script, so that changes in a local dictionary are automatically reflected in the JSON file. I'll leave it to the OS to optimise writes and cache (I don't mind if the file is basically updated dozens of times throughout the running of the script), but ultimately this is just about a kilobyte of metadata that I'd like to keep around. It's not necessary to address concurrent access to this. I'd just like to be able to access a hierarchical structure (like nested dictionary) within the python process and have reads (and writes to) that structure automatically result in reads from (and changes to) a local JSON file.

like image 398
user3325588 Avatar asked Oct 21 '22 03:10

user3325588


2 Answers

well, since python itself has no signals-slots, I guess you can instead make your own dictionary class by inherit it from python dictionary. Class exactly like python dict, only in every method of it that can change dict values you will dump your json.

also you can use smth like PyQt4 QAbstractItemModel which has signals. And when it data changed signal will emitted, do your dumping - it will be only in one place, which is nice.

I know these two are sort of stupid ways, probably yea. :) If anyone knows better, go ahead and tell!

like image 175
Bruno Gelb Avatar answered Oct 22 '22 18:10

Bruno Gelb


This is a developpement from aspect_mkn8rd' answer taking into account Gerrat's comments, but it is too long for a true comment.

You will need 2 special container classes emulating a list and a dictionnary. In both, you add a pointer to a top-level object and override the following methods :

  • __setitem__(self, key, value)
  • __delitem__(self, key)
  • __reversed__(self)

All those methods are called in modification and should have the top-level object to be written to disk.

In addition, __setitem__(self, key, value) should look if value is a list and wrap it into a special list object or if it is a dictionary, wrap it into a special dictionnary object. In both case, the method should set the top-level object into the new container. If neither of them and the object defines __setitem__, it should raise an Exception saying the object is not supported. Of course you should then modify the method to take in account this new class.

Of course, there is a good deal of code to write and test, but it should work - left to the reader as an exercise :-)

like image 24
Serge Ballesta Avatar answered Oct 22 '22 16:10

Serge Ballesta