1

I am writing a class that stores data that I ultimately want to serialize/deserialize to/from disk. Any object of this class can be unambiguously represented as a dictionary containing the data stored in the object’s attributes. Therefore, serializing and deserializing amounts to converting the object to a dictionary representation (or initializing a new object with the dictionary representation), then serializing/deserializing the dict with something like json.dump(), json.read(), etc.

Calling obj.__dict__ isn’t acceptable because I’m wrapping the public attributes with @property decorators to build in write-once functionality, and storing the actual values in non-public variables like _attribute. Therefore, calling obj.__dict__ returns a dictionary with keys like “_attribute” which isn’t what I want.

What is the “right” way to architect such a class? Should I have an obj.to_dict() method (possibly non-public), or write the class such that dict(obj) works? Extending the question, should I have an obj.json_dumps() method, or write the class such that json.dumps(obj) works?

My initial thought was to use the __repr__ method to create the dict representation of the object, then return the string representation of the dict, but it seems like that approach takes one too many steps. According to a previous stackoverflow question, __repr__ should be an unambiguous representation of the object, so I’m happy with __repr__ returning the string representation of a dict, but converting dict -> str -> dict seems like a non-optimal way to go.

I’m trying to avoid a bad architectural pattern, and I’d also like to have the most general architecture possible so that I can trivially implement some other kind of serialization like yaml or pickle in the future.

Community
  • 1
  • 1
joshua.r.smith
  • 917
  • 2
  • 8
  • 19

1 Answers1

1

I might be understanding you wrong but, have you considered JSON?

with open(output_file, 'w') as ff:
      json.dump(obj, ff)
with open(output_file) as ff:
      obj = json.load(ff)

Another option might be the module PICKLE

with open("mierda.txt", 'w') as ff:
     pickle.dump(a, ff)
with open("mierda.txt") as ff: 
     obj = pickle.load(ff)
Jblasco
  • 3,827
  • 22
  • 25
  • I've considered both json and pickle. My question is: what is the most pythonic way to do things? Should I write my class so that it is compatible with those modules, or should my class have methods like, e.g., `obj.json_dump()`? – joshua.r.smith Oct 06 '14 at 19:56
  • Then obviously I'm missing something... How exactly would you need to write your class "to be compatible" with JSON? I'd just write a method "save(file)" (or similar) that calls json.dump on self and another one "read(file)" that calls json.load on the file. – Jblasco Oct 07 '14 at 07:34