storing meta data on dictionary keys

Andreas Kraemer akraemer at
Fri Oct 12 00:40:35 CEST 2007

On Oct 11, 1:42 pm, Erik Jones <e... at> wrote:
> On Oct 11, 2007, at 2:25 PM, Andreas Kraemer wrote:
> > On Oct 11, 10:17 am, Erik Jones <e... at> wrote:
> >> No, duck typing and inheritance are two different things.  Duck
> >> typing is when you implement the same operations as another object or
> >> class, whereas with inheritance you get the same implementation as
> >> that of the parent class.
> > Except when you override a method ...
> Right.  But, that's specialization which is still part of the
> inheritance model, and not duck typing, since you're also inheriting
> state.  Duck typing is about implementing an interface and has
> nothing to do with state.  Put another way, with inheritance you're
> getting both behaviour and state, with duck typing you're mimicking
> behaviour.
> >> With duck typing, an object "acts like"
> >> another object in specific contexts.
> > That's exactly what Str(str) does in the context dictionary look-
> > up ...
> No, in that case Str "is-a" str, it doesn't have to act like a str
> because it is one, whereas with my Node example, Node "acts-like" a
> str (or int or any other hashable).  Read the first sentence of the
> Wikipedia article on duck typing:
> Duck_typing
> >> With inheritance, an object is
> >> the same general type as another object.  You don't want string
> >> objects, you want objects that, in a specific case, act like strings
> >> but in others, I'm sure, not.  How does a concept like string
> >> substitution fit with your inherited objects?
> > Since Str(str) inherits all methods of str, those methods that return
> > other strings (always new objects since str is immutable) like e.g.
> > replace() will return str and not Str(str), and don't have the meta
> > data copied. Which may be a bug or a feature  ...:-)
> > I think the subtle difference here lies between the definition of
> > inheritance and duck-typing, and how both are typically used in
> > practice ...
> Right, here you're wanting to implement your Node as a specialization
> of str in order to get only some of it's behaviour.  But the
> abstractions of a graph node and string don't mix with some of str's
> other behaviour.  To me this is obtuse:
>  >>> class Node(str): pass
> ...
>  >>> n = Node('funky %s')
>  >>> n.children = [Node('child1'), Node('child2')]
>  >>> print n % 'yes
> funky yes
> Duck typing is what you're looking for and is specifically not
> inheritance.
> I'd like to note that my entire argument has been based on the
> semantics of inheritance v. duck typing.  I'm not saying what you're
> doing won't work, just that when I see someone inherit from str I
> expect a str-like object in intention, it being hashable should be
> incidental to that.  This example is sufficiently small and simple
> that if you do choose inheritance you're not likely to get bitten.
> But, once you get in the habit of breaking abstractions like this you
> open yourself up for a world of hurt in other scenarios.
> Another thing to think about is that the only thing you have to gain
> with piggy backing str like this is saving three lines of typing, 4
> lines to implement __hash__ and __eq__ v. 1 line to inherit from str.

I get your point. And you are right, I certainly won't use this
technique for anything larger than in this example. As I mentioned in
my OP, I was using the networkx graph package (BTW an excellent
library IMHO,, and in most cases it is
sufficient (as in the examples on the web site) that nodes *are* just
simple strings or integers. Networkx is about the graph (i.e.
relationships between nodes) and does not use any "internal" node
information except for their identity as defined by __hash__ and
__eq__. That's from where I started ....


More information about the Python-list mailing list