Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #101002

Re: using __getitem()__ correctly

From "Charles T. Smith" <cts.private.yahoo@gmail.com>
Newsgroups comp.lang.python
Subject Re: using __getitem()__ correctly
Date 2015-12-30 16:58 +0000
Organization A noiseless patient Spider
Message-ID <n612fj$rtp$4@dont-email.me> (permalink)
References <n60kcc$h89$1@dont-email.me> <mailman.70.1451481087.11925.python-list@python.org> <n60qcp$rtp$2@dont-email.me> <mailman.76.1451489799.11925.python-list@python.org>

Show all headers | View raw


On Wed, 30 Dec 2015 08:35:57 -0700, Ian Kelly wrote:

> On Dec 30, 2015 7:46 AM, "Charles T. Smith"
> <cts.private.yahoo@gmail.com> wrote:
>> As is so often the case, in composing my answer to your question, I
>> discovered a number of problems in my class (e.g. I was calling
>> __getitem__() myself!), but I'm puzzled now how to proceed.  I thought
>> the way you avoid triggering __getattr__() from within that was to use
>> self.__dict__[name] but that doesn't work:
>>
>>   (PDB)p self.attrs.keys()
>>   ['mcc', 'abc']
>>   (PDB)p self.attrs.__dict__['abc']
>>   *** KeyError: KeyError('abc',)
> 
> What leads you to believe that this is triggering a call to __getattr__?
> The KeyError probably just means that the key 'abc' wasn't found in the
> dict.


I meant, it doesn't work because I'm not getting at the attribute  Although keys()
sees it, it's not in the __dict__ attribute of attrs.  If it's not there, where is it?


>             print "attrdict:av:__getattr__: autovivifying ", name
>             #self.__dict__.__setitem__ (name, self.__class__())
>             #self.__setitem__ (name, self.__class__()) self.__setattr__
>             (name, self.__class__())
> 
> No reason to explicitly call __setitem__ or __setattr__ here. I'd
> probably just do self[name] = self.__class__()


The reason I used this is to avoid trigging the __setitem__() method:

  self.__setattr__(name, self.__class__())

which is invoked if I use the "self[name]" syntax.  But that didn't work.

Is it just impossible to get at attributes without going through either
__getattr__() or __getitem__()?



> Based on the preceding, you probably want to return the value you just
> set in the dict, correct? So just return self[name].


The problem is that then triggers the __getitem__() method and I don't
know how to get to the attributes without triggering __getattr__().

It's the interplay of the two that's killing me.

In the example, if I have:

  self.mcc = self.attrs.mcc


The crux:

Then __getattr__() triggers for the mcc.  If I try to use self.attrs['mcc']
to get it, then that triggers __getitem__().  Okay, if the key is not an int,
I'll go and get it and return it... unfortunately that triggers __getattr__(),
an infinite loop.

I tried using:

    attrdict.__getattr__ (self, 'mcc')

but that didn't help, of course.  I also tried so, but I've got this wrong, somehow:

    super (attrdict, self).__getattr__ ('mcc')






class attrdict(dict):
    def __init__ (self, name = None):
        if name:
            self.update (name)
        print "attrdict: instantiated: ", name
        
    # AutoVivification
    def __getattr__ (self, name):
        print "attrdict:av:__getattr__: entered for ", name
        if name not in self.keys():
            print "attrdict:av:__getattr__: autovivifying ", name
            self[name] = self.__class__()
        return self[name]

    def __getitem__ (self, key):
        print "attrdict:av:__getitem__: entered for ", key
        if type (key) is int:          # TODO: support slices
            return self.__getitem__(key)
        return attrdict.__getattr__(self, key)

    def __setattr__(self, name, value):
        self[name] = value

Back to comp.lang.python | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

using __getitem()__ correctly "Charles T. Smith" <cts.private.yahoo@gmail.com> - 2015-12-30 12:57 +0000
  Re: using __getitem()__ correctly Chris Angelico <rosuav@gmail.com> - 2015-12-31 00:11 +1100
    Re: using __getitem()__ correctly "Charles T. Smith" <cts.private.yahoo@gmail.com> - 2015-12-30 14:40 +0000
      Re: using __getitem()__ correctly Ian Kelly <ian.g.kelly@gmail.com> - 2015-12-30 08:35 -0700
        Re: using __getitem()__ correctly "Charles T. Smith" <cts.private.yahoo@gmail.com> - 2015-12-30 16:58 +0000
          Re: using __getitem()__ correctly Ian Kelly <ian.g.kelly@gmail.com> - 2015-12-30 13:40 -0700
            Re: using __getitem()__ correctly "Charles T. Smith" <cts.private.yahoo@gmail.com> - 2015-12-30 22:54 +0000
              Re: using __getitem()__ correctly "Charles T. Smith" <cts.private.yahoo@gmail.com> - 2015-12-30 22:58 +0000
              Re: using __getitem()__ correctly Ben Finney <ben+python@benfinney.id.au> - 2015-12-31 10:13 +1100
                Re: using __getitem()__ correctly "Charles T. Smith" <cts.private.yahoo@gmail.com> - 2015-12-30 23:18 +0000
                Re: using __getitem()__ correctly Steven D'Aprano <steve@pearwood.info> - 2015-12-31 10:50 +1100
                Re: using __getitem()__ correctly Ben Finney <ben+python@benfinney.id.au> - 2015-12-31 11:21 +1100
                Re: using __getitem()__ correctly "Charles T. Smith" <cts.private.yahoo@gmail.com> - 2015-12-31 11:30 +0000
                Re: using __getitem()__ correctly Ben Finney <ben+python@benfinney.id.au> - 2015-12-31 22:51 +1100
                Re: using __getitem()__ correctly Oscar Benjamin <oscar.j.benjamin@gmail.com> - 2015-12-31 12:12 +0000
                Re: using __getitem()__ correctly "Charles T. Smith" <cts.private.yahoo@gmail.com> - 2015-12-31 13:39 +0000
                Re: using __getitem()__ correctly Steven D'Aprano <steve@pearwood.info> - 2016-01-01 02:03 +1100
                Re: using __getitem()__ correctly "Charles T. Smith" <cts.private.yahoo@gmail.com> - 2015-12-31 11:17 +0000
                Re: using __getitem()__ correctly Steven D'Aprano <steve@pearwood.info> - 2016-01-01 01:43 +1100
              Re: using __getitem()__ correctly Ian Kelly <ian.g.kelly@gmail.com> - 2015-12-30 17:31 -0700
                Re: using __getitem()__ correctly "Charles T. Smith" <cts.private.yahoo@gmail.com> - 2015-12-31 12:45 +0000

csiph-web