add method to class dynamically?
Jean-Paul Calderone
exarkun at divmod.com
Wed Oct 22 08:37:11 EDT 2008
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()
>
>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
More information about the Python-list
mailing list