Dictionary inheritance

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Talin

    #1

    Dictionary inheritance

    I want to make a dictionary that acts like a class, in other words,
    supports inheritance: If you attempt to find a key that isn't present,
    it searches a "base" dictionary, which in turn searches its base, and so on.

    Now, I realize its fairly trivial to code something like this using
    UserDict, but given that classes and modules already have this behavior,
    is there some built-in type that already does this?

    (This is for doing nested symbol tables and such.)

    ---

    Also, on a completely different subject: Has there been much discussion
    about extending the use of the 'is' keyword to do type comparisons a la
    C# (e.g. "if x is list:") ?

    -- Talin

  • Devan L

    #2
    Re: Dictionary inheritance

    Talin wrote:[color=blue]
    > I want to make a dictionary that acts like a class, in other words,
    > supports inheritance: If you attempt to find a key that isn't present,
    > it searches a "base" dictionary, which in turn searches its base, and so on.
    >
    > Now, I realize its fairly trivial to code something like this using
    > UserDict, but given that classes and modules already have this behavior,
    > is there some built-in type that already does this?
    >
    > (This is for doing nested symbol tables and such.)
    >
    > ---
    >
    > Also, on a completely different subject: Has there been much discussion
    > about extending the use of the 'is' keyword to do type comparisons a la
    > C# (e.g. "if x is list:") ?
    >
    > -- Talin[/color]

    Dictionaries aren't classes? I wasn't aware of that. Anyways, what
    you're looking for, I think is a class that emulates a dictionary.
    Probably you should just have some attribute that references a bigger
    dictionary.

    bigger_dict =
    {'foo':1,'baz': 2,'bar':3,'foob ar':4,'foobaz': 5,'foobazbar':6 }
    smaller_dict = {'spam':1,'ham' :2,'bacon':3,'e ggs':4}
    smaller_dict.fa llback = bigger_dict

    and then the __getitem__ method might look something like

    def __getitem__(sel f, key):
    if self.has_key(ke y):
    return self[key]
    else:
    return self.fallback[key]

    Comment

    • Raymond Hettinger

      #3
      Re: Dictionary inheritance

      [Talin][color=blue]
      > I want to make a dictionary that acts like a class, in other words,
      > supports inheritance: If you attempt to find a key that isn't present,
      > it searches a "base" dictionary, which in turn searches its base, and so on.[/color]

      Perhaps the chainmap() recipe will meet your needs:




      Raymond

      Comment

      • Jordan Rastrick

        #4
        Re: Dictionary inheritance

        Talin asked:
        [color=blue]
        > Also, on a completely different subject: Has there been much discussion
        > about extending the use of the 'is' keyword to do type comparisons a la
        > C# (e.g. "if x is list:") ?
        >
        > -- Talin[/color]

        No, is already has a specific, well defined meaning - object identity.

        IDLE 1.1[color=blue][color=green][color=darkred]
        >>> a = [1,2,3]
        >>> a is list[/color][/color][/color]
        False[color=blue][color=green][color=darkred]
        >>> b = type(a)
        >>> b[/color][/color][/color]
        <type 'list'>[color=blue][color=green][color=darkred]
        >>> b is list[/color][/color][/color]
        True

        "Extending it" to mean something entirely different to what it
        currently means is a bad idea, and is also unnessecary - the builtin
        function isinstance already provides the functionaliy you're looking
        for:
        [color=blue][color=green][color=darkred]
        >>> isinstance(b, list)[/color][/color][/color]
        False[color=blue][color=green][color=darkred]
        >>> isinstance(a, list)[/color][/color][/color]
        True[color=blue][color=green][color=darkred]
        >>>[/color][/color][/color]

        However, use sparingly - calling isinstance unnessecarily rather than
        relying on polymorphism is considered pretty unpythonic, and usually
        reflects pretty poor OO design.

        Comment

        • bruno modulix

          #5
          Re: Dictionary inheritance

          Devan L wrote:[color=blue]
          > Talin wrote:
          >[color=green]
          >>I want to make a dictionary that acts like a class, in other words,
          >>supports inheritance:[/color][/color]
          (snip)[color=blue]
          >
          > Dictionaries aren't classes?[/color]

          They are.

          --
          bruno desthuilliers
          python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
          p in 'onurb@xiludom. gro'.split('@')])"

          Comment

          • bruno modulix

            #6
            Re: Dictionary inheritance

            Talin wrote:[color=blue]
            > I want to make a dictionary that acts like a class, in other words,
            > supports inheritance:[/color]

            I must be missing your point here, since dict is a class and as such
            support inheritence:
            [color=blue][color=green][color=darkred]
            >>> class MyDict(dict):pa ss[/color][/color][/color]
            ....[color=blue][color=green][color=darkred]
            >>> d = MyDict()
            >>> d.items()[/color][/color][/color]
            [][color=blue][color=green][color=darkred]
            >>>[/color][/color][/color]

            [color=blue]
            > If you attempt to find a key that isn't present,
            > it searches a "base" dictionary, which in turn searches its base, and so
            > on.[/color]

            That's not inheritence, that's contextual acquisition (Zope relies
            heavily on this concept).
            [color=blue]
            > Now, I realize its fairly trivial to code something like this using
            > UserDict,[/color]

            If you want to specialize dict, why use UserDict ?
            [color=blue]
            > but given that classes and modules already have this behavior,[/color]

            Nope. Inheritence is not the solution - unless of course you want to
            create a derived class for each and any of your 'nested dict' instances,
            which would be a rather strange design...


            Here you need composition/delegation:

            class HierDict(dict):
            def __init__(self, parent=None):
            self._parent = parent

            def __getitem__(sel f, name):
            try:
            return super(HierDict, self).__getitem __(name)
            except KeyError, e:
            if self._parent is None:
            raise
            return self._parent[name]

            # to be continued according to your needs


            if __name__ == "__main__":
            d = HierDict(None)
            d['test'] = 42
            print d['test']

            d2 = HierDict(d)
            d2['dead'] = "parrot"

            print d2['dead'] # found in d2
            print d2['test'] # found in d

            [color=blue]
            >
            > Also, on a completely different subject: Has there been much discussion
            > about extending the use of the 'is' keyword to do type comparisons a la
            > C# (e.g. "if x is list:") ?[/color]

            I don't think there is much to discuss:

            x = list
            if x is list:
            print "x is list"

            Remember that in Python,
            1/ type information pertains to objects, not to identifiers
            2/ types are objects too

            So, the 'is' operator being the identity operator, there is no need to
            'extend' it to do type comparisons:

            x = []
            if type(x) is type([]):
            print "x is a list"

            But - even if useful in some special cases -, type comparisons in
            Python are rarely necessary and in most case worst than useless:

            def get_foo(a_dict) :
            if type(a_dict) is type({}):
            foo = a_dict['foo']
            else:
            raise TypeError, "expected a dict, got something else"

            h = HierDict()
            h['foo'] = 'bar'

            get_foo(h)


            ....definitivel y worst than useless...

            -
            bruno desthuilliers
            python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
            p in 'onurb@xiludom. gro'.split('@')])"

            Comment

            • Elmo Mäntynen

              #7
              Re: Dictionary inheritance

              On Fri, 12 Aug 2005 12:44:11 -0700, Talin wrote:
              [color=blue]
              > I want to make a dictionary that acts like a class, in other words,
              > supports inheritance: If you attempt to find a key that isn't present,
              > it searches a "base" dictionary, which in turn searches its base, and so on.
              >
              > Now, I realize its fairly trivial to code something like this using
              > UserDict, but given that classes and modules already have this behavior,
              > is there some built-in type that already does this?
              >
              > (This is for doing nested symbol tables and such.)
              >
              > ---[/color]

              You could always do:

              class nestedDict(dict ):
              ...

              Comment

              Working...