Syntax when dereferencing database-backed tree
I'm using MongoDB, so my clusters of data are in dictionaries. Some of these contain references to other Mongo objects. For example, say I have a Person document which has a separate Employer document. I would like to control element access so I can automatically dereference documents. I also have some data with dates, and since PyMongo can't store timezone info, I'd like to store a string timezone alongside the UTC time and have an accessor to the converted times easily.
Which of these options seems the best to you?
Person = {'employer': ObjectID}
Employer = {'name': str}
Option 1: Augmented operations are methods
- Examples
print person.get_employer()['name']
person.get_employer()['name'] = 'Foo'
person.set_employer(new_employer)
- Pro: Method syntax makes it clear that getting the employer is not just dictionary access
- Con: Differences between the syntaxes between referenced objects and not, making it hard to normalize the schema if necessary. Augmenting an element would require changing the callers
Option 2: Everything is an attribute
- Examples
print person.employer.name
person.employer.name = 'Foo'
person.employer = new_employer
- Pro: Uniform syntax for augmented and non-augmented
- ?: Makes it unclear that this is backed by a dictionary, 开发者_如何学编程but provides a layer of abstraction?
- Con: Requires morphing a dictionary to an object, not pythonic?
Option 3: Everything is a dictionary item
- Examples
print person['employer']['name']
person['employer']['name'] = 'Foo'
person['employer'] = new_employer
- Pro: Uniform syntax for augmented and non-augmented
- ?: Makes it unclear that some of these accesses are actually method calls, but provides a layer of abstraction?
- Con: Dictionary item syntax is error-prone to type IMHO.
Your first 2 options would require making a "Person" class and an "Employer" class, and using __dict__
to read values and setattr
for writing values. This approach will be slower, but will be more flexible (you can add new methods, validation, etc.)
The simplest way would be to use only dictionaries (option 3). It wouldn't require any need for oop. Personally, I also find it to be the most readable of the 3.
So, if I were you, I would use option 3. It is nice and simple, and easy to expand on later if you change your mind. If I had to choose between the first two, I would choose the second (I don't like overusing getters and setters).
P.S. I'd keep away from person.get_employer()['name'] = 'Foo'
, regardless of what you do.
Do not be afraid to write a custom class when that will make the subsequent code easier to write/read/debug/etc.
Option 1 is good when you're calling something that's slow/intensive/whatever -- and you'll want to save the results so can use option 2 for subsequent access..
Option 2 is your best bet -- less typing, easier to read, create your classes once then instantiate and away you go (no need to morph your dictionary).
Option 3 doesn't really buy you anything over option 2 (besides more typing, plus allowing typos to pass instead of erroring out)
精彩评论