class Foo:
def __init__(self, obj):
self.obj = obj
def __getattr__(self, name):
return getattr(self.obj, name)
foo = Foo([1,2,3])
print foo[2] # prints 3
I would expect the code to raise an exception, since there is no __getitem__
method. A quick test learns that this is apparently a feature new to 2.2;
it doesn't work if I try it in 2.1.
Interestingly, using getattr() directly on a list does *not* work (although
this is what the method does):
>>> x = [1, 2, 3]
>>> getattr(x, 1)
Traceback (most recent call last):
File "<pyshell#1>", line 1, in ?
getattr(x, 1)
TypeError: attribute name must be string
>>> getattr(x, "1")
Traceback (most recent call last):
File "<pyshell#2>", line 1, in ?
getattr(x, "1")
AttributeError: 'list' object has no attribute '1'
I didn't find anything about this in the reference manual. Does anybody know
how/why this works and why it was added?
Cheers,
--
Hans (base64.decodestring('d3VybXlAZWFydGhsaW5rLm5ldA=='))
# decode for email address ;-)
The Pythonic Quarter:: http://www.awaretek.com/nowak/
I think what's happening here is that invoking
the [] is causing a lookup for a __getitem__
method, and your __getattr__ is catching this
and redirecting it to self.obj, which does
have a __getitem__ method.
> A quick test learns that this is apparently a
> feature new to 2.2;
The new feature is that built-in types now
have all the relevant special methods accessible
by __xxx__ names. Previously they only worked
on user-defined classes.
> Does anybody
> know how/why this works and why it was added?
I don't think it was explicitly added -- it's
just a side effect of the type/class unification
stuff.
Greg Ewing, Computer Science Dept,
University of Canterbury,
Christchurch, New Zealand
http://www.cosc.canterbury.ac.nz/~greg