setattr question

T

TP

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__") )
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 !


--
python -c "print ''.join([chr(154 - ord(c)) for c in '*9(9&(18%.\
9&1+,\'Z4(55l4('])"

"When a distinguished but elderly scientist states that something is
possible, he is almost certainly right. When he states that something is
impossible, he is very probably wrong." (first law of AC Clarke)
 
P

Peter Otten

TP said:
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):
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:
.... 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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,962
Messages
2,570,134
Members
46,690
Latest member
MacGyver

Latest Threads

Top