storing meta data on dictionary keys
Erik Jones
erik at myemma.com
Thu Oct 11 16:42:01 EDT 2007
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.
Erik Jones
Software Developer | Emma®
erik at myemma.com
800.595.4401 or 615.292.5888
615.292.0777 (fax)
Emma helps organizations everywhere communicate & market in style.
Visit us online at http://www.myemma.com
More information about the Python-list
mailing list