storing meta data on dictionary keys

Andreas Kraemer akraemer at sbcglobal.net
Thu Oct 11 18:40:35 EDT 2007


On Oct 11, 1:42 pm, Erik Jones <e... at myemma.com> wrote:
> On Oct 11, 2007, at 2:25 PM, Andreas Kraemer wrote:
>
> > On Oct 11, 10:17 am, Erik Jones <e... at myemma.com> 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:http://en.wikipedia.org/wiki/
> 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, https://networkx.lanl.gov/wiki), 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 ....

Andreas




More information about the Python-list mailing list