add method to class dynamically?

Gabriel Genellina gagsl-py2 at yahoo.com.ar
Thu Oct 23 04:06:35 CEST 2008


En Wed, 22 Oct 2008 10:37:11 -0200, Jean-Paul Calderone  
<exarkun at divmod.com> escribió:

> On Wed, 22 Oct 2008 08:29:08 -0400, Neal Becker <ndbecker2 at gmail.com>  
> 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




More information about the Python-list mailing list