setattr question
Peter Otten
__peter__ at web.de
Thu Feb 19 12:38:46 EST 2009
TP wrote:
> Hi everybody,
>
> I try to make a "link" (or shortcut, if you want) so that len(b_instance)
> computes in fact len(a) (see the code below). I could write a method
> __len__ to b, but I wonder if it is possible to make it with a
> setattr/getattr trick, as I do below.
>
> Thanks in advance,
>
> Julien
>
> ######################
> class b( object ):
>
> def __init__( self ):
>
> super( b, self ).__init__()
>
> a = [5,4,7]
> b_instance = b()
>
> setattr( b_instance, "__len__", getattr( a, "__len__") )
Invoking setattr() or getattr() with a constant name is bogus. The above can
be written as
b_instance.__len__ = a.__len__
> print len( a )
> print id( a.__len__ )
> print hasattr( b_instance, "__len__" )
> print id( b.__len__ )
> print len( b_instance )
> ########################
>
> I obtain:
> $ p test_setattr.py
> 3
> 3083822540
> True
> Traceback (most recent call last):
> File "test_setattr.py", line 14, in <module>
> print id( b.__len__ )
> AttributeError: type object 'b' has no attribute '__len__'
> Command failure: error 1 !
>
__special__ methods in newstyle classes are looked up in the class, not the
instance:
>>> class B(object): pass
...
>>> items = [1,2,3]
>>> b = B()
>>> len(b)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: object of type 'B' has no len()
>>> B.__len__ = items.__len__
>>> len(b)
3
Now that doesn't make much sense because all instances of B now share the
same length. If you want a useful per-instance length function you have to
delegate:
>>> class B(object):
... def __len__(self): return self._len()
...
>>> a = B()
>>> b = B()
>>> a._len = [1,2,3].__len__
>>> b._len = [].__len__
>>> len(a), len(b)
(3, 0)
Peter
More information about the Python-list
mailing list