Modifying an instances dict to change attribute lookup

Discussion in 'Python' started by jslowery@gmail.com, Feb 20, 2006.

  1. Guest

    Hmm, I know this is something fundamental about how Python implements
    predicate dispatch, but for some reason I believed that this would
    work:

    class delegate_dict(dict):
    def __init__(self, orig, deleg):
    dict.__init__(self, orig)
    self.deleg = deleg

    def __getitem__(self, name):
    print 'here:', name
    try:
    v = dict.__getitem__(self, name)
    except KeyError:
    return self.deleg.__getitem__(name)
    return v

    def delegate(target, source):
    target.__dict__ = delegate_dict(target.__dict__, source.__dict__)

    As a simple usage, give:


    class A(object):
    pass

    class B(object):
    def __init__(self, o):
    delegate(self, o)

    a = A()
    a.test = 1
    b = B(a)
    print b.__dict__.__getitem__('test')

    # This goes down in flames
    print b.test


    And then a dumb example showing the concept I assumed was a given:

    class C(object):
    pass

    c = C()
    c.x = 1
    assert c.__dict__.__getitem__('x') == c.x

    Could someone please tell me why the first example using a customized
    dict does not perform as advertised?
    , Feb 20, 2006
    #1
    1. Advertising

  2. <> wrote:
    ...
    > c = C()
    > c.x = 1
    > assert c.__dict__.__getitem__('x') == c.x
    >
    > Could someone please tell me why the first example using a customized
    > dict does not perform as advertised?


    Because Python's __getattribute__ is currently not EXACTLY as you
    imagine it to be, but slightly different, say something like:
    dict.__getitem__(c, 'x')
    at the crucial step rather than c.__getitem__. More generally, when (on
    any type or newstyle class -- oldstyle legacy classes are different) a
    special method gets implicitly invoked, it's invoked on the type, not on
    the instance (no per-instance overriding in this case); and, for speed,
    many internal dict lookups do "dict.__getitem__(obj,name)" rather than
    "type(obj).__getitem__(obj, name)".

    The documented way to do what you want in Python is by overriding
    __getattr__ (which gets called when other normal lookup procedures fail
    and would, absent __getattr__, raise AttributeError), not by trying to
    install as the __dict__ something whose type isn't exactly __dict__.
    Other approaches may work, but they depend on implementation accidents
    which are liable to change with every passing breeze.


    Alex
    Alex Martelli, Feb 20, 2006
    #2
    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. John Wohlbier
    Replies:
    2
    Views:
    358
    Josiah Carlson
    Feb 22, 2004
  2. M. Clift

    Dict lookup shortcut?

    M. Clift, Oct 12, 2004, in forum: Python
    Replies:
    5
    Views:
    309
    M. Clift
    Oct 13, 2004
  3. Guest
    Replies:
    6
    Views:
    382
    Guest
    Sep 4, 2007
  4. Aaron Brady

    reverse dict lookup & Relation class

    Aaron Brady, Jan 15, 2009, in forum: Python
    Replies:
    8
    Views:
    379
    Aaron Brady
    Jan 18, 2009
  5. Steven D'Aprano

    Unexpected comparisons in dict lookup

    Steven D'Aprano, Mar 18, 2014, in forum: Python
    Replies:
    1
    Views:
    57
    Ian Kelly
    Mar 18, 2014
Loading...

Share This Page