En Wed, 22 Oct 2008 10:37:11 -0200, Jean-Paul Calderone
<[EMAIL PROTECTED]> escribió:
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()
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.
All special methods have names like "__special__" (except "next" -used in
the iterator protocol- which will become __next__ in 3.0; any others?) -
this is stated here
http://docs.python.org/reference/lexical_analysis.html#reserved-classes-of-identifiers.
(But I'm sure you already knew that)
To the OP: you may use a "template method". In the C++ class do the
equivalent of:
class Ring_int(int):
def __len__(self): return self._len_impl()
def _len_impl(self): raise NotImplementedError
Now you can override _len_impl in the instance:
py> r = Ring_int(10)
py> r._len_impl = lambda: 10
py> len(r)
10
Note that hasattr(r, '__len__') is true, don't use that check in this case.
--
Gabriel Genellina
--
http://mail.python.org/mailman/listinfo/python-list