storing meta data on dictionary keys

Andreas Kraemer akraemer at sbcglobal.net
Thu Oct 11 02:36:27 EDT 2007


On Oct 10, 9:00 pm, Erik Jones <e... at myemma.com> wrote:
> If you're sure that 1.  this use case won't grow and 2. that you'll
> only be the only person ever using code, then it's your choice of
> preference.  Both of those points are equally important.  1 is a
> manageability issue in that you are complicating what could be an
> easy solution for a small gain in convenience -- one that could just
> as easily be had by encapsulating the management of both dicts in an
> explicit class or function/method.  Let me quote lines 2 through 5 of
> The Zen of Python (PEP20):
>
> Explicit is better than implicit.
> Simple is better than complex.
> Complex is better than complicated.
> Flat is better than nested.
>
> Using two dicts would be explicit, simple and flat.  Your's is none
> of those.
>
> For point 2, if anyone else needs to work with your code they're most
> likely going to be confused as the implementation is overly complex.
> I know when I initially read through it I had to read it a couple
> times to assure myself of what it was doing because I was thinking
> that it seems that there's more going on than there is, so there must
> be.  Remember, the best solutions are those that not only you can
> understand, but the next guy/girl/?.

You are right, and these are all very valid points. One of the reasons
I like Python so much is the philosophy behind it. Nevertheless,
everything is relative, so a pattern that seems complex (or unusual)
at first may become simple when people get used to it ... I hope, I
may be excused. In the organization where I work I am mainly
prototyping (more on the "scientific/algorithm" side) and not required
to write maintainable code. The engineers will do that (in Java
anyway, sadly ..).

> > The trivial "class Str(str): pass" in the OP (that already inherits
> > the correct __hash__ and
> > __eq__) serves the same purpose as your Node(object) below, ...
>
> True, but you're breaking the intended abstraction of inheriting from
> str, i.e. the reason you can inherit from str is so that you can
> specialize strings, not get __has__ and __eq__ for free.  You can
> define those on your own for a reason.

Who says that that's the intended abstraction of inheriting from str?
I thought that one purpose of inheritance was the reuse of behavior
(i.e. methods) (and maybe state) of the superclass. So, my class
Str(str): pass behaves like a string in all aspects, except that you
can attach some meta data that won't affect that behavior. In fact, I
use that pattern quite frequently also for other built-in immutable
types, e.g. floats or ints, which allows me to very easily "tag"
numerical data (e.g. as an outlier in a stats application or whatever)
without affecting any subsequent code operating on it as long as it
only uses its built-in "flavor". This is the power of Python's duck
typing!

> So, (explicitly:) you want the built-in dict to be a dictionary that
> also maintains a dictionary of its own keys?

Without knowing the internals, so I may be wrong. But dict must
somehow maintain a dictionary of the key objects already. How else
could it detect collisions of hash values, when it must use __eq__ to
determine equality of the "query" key object to one of the inserted
keys having the same hash value? It also needs to do the same check
when overwriting an existing key.

> Not likely to happen.
> Again, you're asking to have one dictionary act as two and that's
> just confusing.  I'm not saying that get_key is a bad idea for
> (possibly) some use cases, just that what you're actually doing is
> creating a dictionary wherein the same key can return two different
> object depending on the retrieval method used and that is NOT what
> the built-in dict is for.  In fact, now that I think of it, get_key
> is probably a bad name for it, get_other_object_with_this_same_key is
> probably more apt :)

Or more precise:
get_key_that_was_used_when_value_was_inserted_into_dictionary :-)

Thanks, for taking the time for this elaborate response!

Cheers,
Andreas







More information about the Python-list mailing list