Travis Griggs wrote: > I really like pymongo. And I really like Python. But one thing my fingers > really get tired of typing is > > someDoc[‘_’id’]
I've never used pymongo, so can't comment from experience, but surely any library which encourages, if not requires, that you access private data _id doesn't inspire me with confidence. Also, the above is a syntax error, but you probably know that. > This just does not roll of the fingers well. Too many “reach for modifier > keys” in a row. *One* modifier key in a row is too many? s o m e SHIFT D o c [ ' SHIFT _ i d ' ] You can cut that by 50% by changing your naming convention: somedoc['_id'] While you're at it, you can cut the total number of keystrokes too: doc['_id'] If there are a fixed set of key names that you use repeatedly, you can do this: ID, FE, FI, FO, FUM = '_id', '_fe', '_fi', '_fo', '_fum' # later someDoc[ID] Ah, but that needs the shiftkey... well, I guess that PEP 8 naming conventions aren't compulsory, and so long as you don't need the built-in `id` function, it's okay to shadow it (consenting adults and all that), so: id, fe, fi, fo, fum = '_id', '_fe', '_fi', '_fo', '_fum' # later someDoc[id] > I would rather use > someDoc._id That has exactly the same number of modifier keys as your original example. I'm starting to sense that you don't actually care about the SHIFT key... [...] > The problem I have is not how to do the AttributeDictionary subclass, > there are plenty of those examples. The problem is that the pymongo APIs > already return dictionaries. In a language (Smalltalk, Objective-C, Ruby) > that supports class extensions, that would be my first tool of choice to > solve this problem. I’d just extend Dictionary to behave the way I want > and be done with it. I can’t do that in Python though. I guess I could > make my own module that subclasses the relevant pymongo classes, and do > super() calling implementations of all of the relevant methods, coercing > the return type. That is a maintenance headache though. > > What are my options, if any? HingTFU comes to mind :-) But as "an academic exercise" *nudge nudge, wink wink* there's always the Adaptor design pattern. Import as much or as little of pymongo as you need, wrap it in an adaptor, and use that. There are lots of different ways that you could do this, some more monkey-patchy than others. # pymongo adaptor module (untested) from pymongo import * import functools def wrap(name): """Wrap function called `name` so it returns an AttrDict instead of dict. May the gods have mercy on your soul.""" func = globals()[name] @functools.wraps(func) def inner(*args, **kwargs): result = func(*args, **kwargs) if isinstance(result, dict): result = AttrDict(result) return result globals()[name] = func FUNCTIONS_THAT_RETURN_DICTS = ['this', 'that', 'another'] for name in FUNCTIONS_THAT_RETURN_DICTS: wrap(name) Extending this to use introspection to automatically detect the pymongo functions instead of having to list them manually is left as an exercise. (Hint: import pymongo; for obj in vars(pymongo): ...). Extending this to wrap methods of classes is also left as an exercise. (Hint: don't subclass. Search the ActiveState Python recipes for "automatic delegation" by Alex Martelli.) And now just use the adaptor module instead of the original. -- Steven -- https://mail.python.org/mailman/listinfo/python-list