__getitem__ on new-style classes

Discussion in 'Python' started by simon@arrowtheory.com, Mar 11, 2005.

  1. Guest

    What i'm trying to do is tie special methods of a "proxy" instance
    to another instance:

    def test1():
    class Container:
    def __init__( self, data ):
    self.data = data
    self.__getitem__ = self.data.__getitem__

    data = range(10)
    c = Container(data)
    print "test1"
    print c[3]

    This works OK. But when I try the same thing on
    new style classes:

    def test2():
    print "test2"
    class Container(object):
    def __init__( self, data ):
    self.data = data
    # self.__dict__["__getitem__"] = self.data.__getitem__
    self.__setattr__( "__getitem__", self.data.__getitem__ )
    data = range(10)
    c = Container(data)
    print
    print c.__getitem__(3) # works OK
    print c[3] # fails

    I get a "TypeError: unindexable object". It
    seems that c[] does not call __getitem__ in this case.

    The plot thickens, however, when one tries the following:

    def test3():
    data = range(10)
    c = type( "Container", (), { "__getitem__":data.__getitem__ } )()
    print "test3"
    print c[3]

    Which works fine. However, if I need to resort to
    such trickery, no-one here where i work will have any idea
    what it does :)

    Would anyone like to shed some light on what is going on here ?

    bye,

    Simon.
     
    , Mar 11, 2005
    #1
    1. Advertising

  2. wrote:
    > What i'm trying to do is tie special methods of a "proxy" instance
    > to another instance:

    ....
    > new style classes:
    >
    > def test2():
    > print "test2"
    > class Container(object):
    > def __init__( self, data ):
    > self.data = data
    > # self.__dict__["__getitem__"] = self.data.__getitem__
    > self.__setattr__( "__getitem__", self.data.__getitem__ )
    > data = range(10)
    > c = Container(data)
    > print
    > print c.__getitem__(3) # works OK
    > print c[3] # fails



    >
    > I get a "TypeError: unindexable object". It
    > seems that c[] does not call __getitem__ in this case.

    because __getitem__ is looked up in the class, not the instance dictionary
    >
    > The plot thickens, however, when one tries the following:
    >
    > def test3():
    > data = range(10)
    > c = type( "Container", (), { "__getitem__":data.__getitem__ } )()
    > print "test3"
    > print c[3]


    Here you've created an entry in the class dictionary, just like writing
    data = range(10)
    class Container(object):
    __getitem__ = data.__getitem__

    but, this probably doesn't help you much if you want the method to delegate to
    an attribute of the instance, since the instance is unavailable at class
    definition time

    So, one solution, is to use create a delegating descriptor, like so:

    class Delegate(object):
    def __init__(self, attrname):
    self.attrname = attrname
    def __get__(self, obj, cls):
    if isinstance(obj, cls):
    # Note that the attribute is looked up on obj._data
    return getattr(obj._data, self.attrname)
    else:
    return self

    class Example(object):
    __getitem__ = Delegate("__getitem__")

    def __init__(self, delegate):
    self._data = delegate

    >>> e = Example(range(10))
    >>> e[3]

    3


    Michael
     
    Michael Spencer, Mar 11, 2005
    #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. KanZen

    __getitem__ and arguments

    KanZen, Jul 19, 2003, in forum: Python
    Replies:
    4
    Views:
    783
    Ben Finney
    Jul 19, 2003
  2. Replies:
    21
    Views:
    1,105
    Steven Bethard
    Mar 16, 2005
  3. ankit
    Replies:
    1
    Views:
    369
    Alex Martelli
    Dec 22, 2005
  4. Isaac Rodriguez

    Are all classes new-style classes in 2.4+?

    Isaac Rodriguez, Dec 31, 2006, in forum: Python
    Replies:
    4
    Views:
    403
    Steven D'Aprano
    Dec 31, 2006
  5. Quek
    Replies:
    3
    Views:
    353
Loading...

Share This Page