storing meta data on dictionary keys

Erik Jones erik at
Thu Oct 11 22:42:01 CEST 2007

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  

>> 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: 

>> 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  

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.

Erik Jones

Software Developer | Emma®
erik at
800.595.4401 or 615.292.5888
615.292.0777 (fax)

Emma helps organizations everywhere communicate & market in style.
Visit us online at

More information about the Python-list mailing list