__contains__ vs. __getitem__

Discussion in 'Python' started by David Isaac, Aug 9, 2006.

  1. David Isaac

    David Isaac Guest

    I have a subclass of dict where __getitem__ returns None rather than
    raising KeyError for missing keys. (The why of that is not important for
    this question.)

    I was delighted to find that __contains__ still works as before
    after overriding __getitem__. So even though instance['key']
    does not raise KeyError, I still get (as desired) 'key' in instance ==
    False.

    Looking forward:
    Can I count on this independence of __getitem__ and __contains__?
    I would like to understand whether it will be safe to count on this
    behavior.

    Thank you,
    Alan Isaac
    David Isaac, Aug 9, 2006
    #1
    1. Advertising

  2. David Isaac wrote:
    > I have a subclass of dict where __getitem__ returns None rather than
    > raising KeyError for missing keys. (The why of that is not important for
    > this question.)


    Well, actually it may be important... What's so wrong with d.get('key')
    that you need this behaviour ?
    Bruno Desthuilliers, Aug 9, 2006
    #2
    1. Advertising

  3. David Isaac

    Guest

    That's a vague question, so the obligatory "it depends" response
    applies here.

    If you want to guard against the unexpected, perhaps it's a good idea
    to write unit tests rather than to take someone's word that it *should*
    work okay every time, in every case, no matter what you're doing with
    the data. Think of what behavior would be disasterous (whether it seems
    possible or not), then write a test for that behavior. Also write tests
    for things that "obviously" *should* hold true... just to make sure
    they hold true.

    Maybe you can't think of ways that this class could possibly screw
    things up, but it's always nice to have reassurance anyway :) The
    closest thing to certainty about code is to test it.

    David Isaac wrote:
    > I have a subclass of dict where __getitem__ returns None rather than
    > raising KeyError for missing keys. (The why of that is not important for
    > this question.)
    >
    > I was delighted to find that __contains__ still works as before
    > after overriding __getitem__. So even though instance['key']
    > does not raise KeyError, I still get (as desired) 'key' in instance ==
    > False.
    >
    > Looking forward:
    > Can I count on this independence of __getitem__ and __contains__?
    > I would like to understand whether it will be safe to count on this
    > behavior.
    >
    > Thank you,
    > Alan Isaac
    , Aug 9, 2006
    #3
  4. On Wed, 09 Aug 2006 16:51:23 GMT
    "David Isaac" <> wrote:

    > Looking forward:
    > Can I count on this independence of __getitem__ and __contains__?
    > I would like to understand whether it will be safe to count on this
    > behavior.



    With the builtin 'dict' implementation, dict.__contains__() use the
    dict_has_key() C function, and does not touch your subclass __getitem__
    python method. I don't think it can be called 'safe'... it may lead to
    very inconsistent behavior. It's like overridind both __eq__ and __ge__
    with a different behavior. It's better for you to override
    __contains__() too.


    --
    Pedro Werneck
    Pedro Werneck, Aug 9, 2006
    #4
  5. David Isaac

    David Isaac Guest

    > Alan Isaac wrote:
    > > I have a subclass of dict where __getitem__ returns None rather than
    > > raising KeyError for missing keys. (The why of that is not important

    for
    > > this question.)


    "Bruno Desthuilliers" <> wrote:
    > Well, actually it may be important... What's so wrong with d.get('key')
    > that you need this behaviour ?


    I want to use the mapping with string interpolation.

    Alan Isaac
    David Isaac, Aug 9, 2006
    #5
  6. David Isaac wrote:
    >> Alan Isaac wrote:
    >>> I have a subclass of dict where __getitem__ returns None rather than
    >>> raising KeyError for missing keys. (The why of that is not important

    > for
    >>> this question.)

    >
    > "Bruno Desthuilliers" <> wrote:
    >> Well, actually it may be important... What's so wrong with d.get('key')
    >> that you need this behaviour ?

    >
    > I want to use the mapping with string interpolation.
    >

    Well, this makes sens... But then why not use a plain dict to collect
    data, and wrap it in a special one just before using it for
    interpolation ? ie:

    class MyDictWrapper(object):
    def __init__(self, d, default=None):
    self._d = d
    self._default = default
    def __getitem__(self, key):
    return self._d.get(key, self._default)


    def render(d):
    tpl = "%(who)s says '%(say)s' and the %(what)s is %(state)s."
    return tpl % MyDictWrapper(d)

    This would avoid any potential trouble with using a strange kind of dict
    in other parts of the code...

    My 2 cents...
    Bruno Desthuilliers, Aug 10, 2006
    #6
  7. Pedro Werneck <> wrote:

    > On Wed, 09 Aug 2006 16:51:23 GMT
    > "David Isaac" <> wrote:
    >
    > > Looking forward:
    > > Can I count on this independence of __getitem__ and __contains__?
    > > I would like to understand whether it will be safe to count on this
    > > behavior.

    >
    > With the builtin 'dict' implementation, dict.__contains__() use the
    > dict_has_key() C function, and does not touch your subclass __getitem__
    > python method. I don't think it can be called 'safe'... it may lead to
    > very inconsistent behavior. It's like overridind both __eq__ and __ge__
    > with a different behavior. It's better for you to override
    > __contains__() too.


    I think it's perfectly safe -- that's what defaultdict in Python 2.5
    does, after all.


    Alex
    Alex Martelli, Aug 11, 2006
    #7
  8. Bruno Desthuilliers <> wrote:

    > David Isaac wrote:
    > >> Alan Isaac wrote:
    > >>> I have a subclass of dict where __getitem__ returns None rather than
    > >>> raising KeyError for missing keys. (The why of that is not important

    > > for
    > >>> this question.)

    > >
    > > "Bruno Desthuilliers" <> wrote:
    > >> Well, actually it may be important... What's so wrong with d.get('key')
    > >> that you need this behaviour ?

    > >
    > > I want to use the mapping with string interpolation.
    > >

    > Well, this makes sens... But then why not use a plain dict to collect
    > data, and wrap it in a special one just before using it for
    > interpolation ? ie:


    Using a single container (and being able to modify and use it fluidly)
    is simply handier. That's what defaultdict in Python 2.5 is for, btw.


    Alex
    Alex Martelli, Aug 11, 2006
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Skip Montanaro
    Replies:
    1
    Views:
    331
    Alex Martelli
    Oct 20, 2003
  2. Anand S Bisen
    Replies:
    2
    Views:
    2,226
    Steve Holden
    Mar 4, 2005
  3. Replies:
    5
    Views:
    275
    Gabriel Genellina
    Apr 12, 2007
  4. Replies:
    3
    Views:
    287
    Hrvoje Niksic
    Sep 21, 2007
  5. Replies:
    4
    Views:
    420
    Colin J. Williams
    Sep 24, 2007
Loading...

Share This Page