On Wed, 22 Oct 2008 08:29:08 -0400, Neal Becker <[EMAIL PROTECTED]> wrote:
I have a class (actually implemented in c++ using boost::python).  For an 
instance of this class, 'r', I'd like to support len (r).  I don't want to add 
it to the c++ code, because this is a unique situation: this class should not 
normally support len().

So I try:
r = ring_int (10)
r.__len__ = lambda: 10

This doesn't work:
len(r)
TypeError: object of type 'ring_int' has no len()

It appears that __len__ is being looked up only on the class dict, not the 
instance dict?  What's the correct way to do this?  (Of course, I could just 
use inheritance, but this is an opportunity for me to learn more about python)


I don't really know anything about the kind of classes that boost makes,
however the behavior you describe is like the behavior of new-style
classes:

 >>> class x: pass
... >>> y = x()
 >>> y.__len__ = lambda: 10
 >>> len(y)
 10
 >>> class x(object): pass
... >>> y = x()
 >>> y.__len__ = lambda: 10
 >>> len(y)
 Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
 TypeError: object of type 'x' has no len()
>>>
Special methods aren't looked up in the instance dict of instances of
new-style classes.  Exactly what constitutes the set of "special methods"
is a bit undefined.  Consider anything that CPython has to look up to
satisfy some other operation, such as len or +, to be a special method
and don't rely on _either_ it being looked up on the instance or it _not_
being looked up on the instance (ie, don't put a method there and expect it
not to be called).  The methods which are actually considered special by
CPython can change and has in the past.

Jean-Paul
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to