But this does work, or something close to it:
... print 'in handler'
...
Traceback (most recent call last):
in handler
Or you can doctor up a Foobar that treats all
function attributes of its instances as methods
to be bound to the specific instance, e.g.,
(not tested beyond what you see)
... def __getattribute__(self, attr):
... sentinel = object()
... atto = object.__getattribute__(self, '__dict__').get(attr, sentinel)
... if hasattr(atto, '__get__'): return atto.__get__(self, type(self))
... elif atto is sentinel: return object.__getattribute__(self, attr)
... return atto
... Traceback (most recent call last):
File "<stdin>", line 1, in ?
'ordinary'
Try another Foobar instance:
Traceback (most recent call last):
File "<stdin>", line 1, in ?
g's own handler for <__main__.Foobar object at 0x02EF134C>
BTW new.instancemethod(handler, f) seems to duplicate handler.__get__(f),
leaving out the type(f) in handler.__get__(f, type(f)) that would make a bound method,
which is what it is, and which could be set as attribute of anything.
Note the difference between newh which sticks with the f
passed to new.instancemethod, and real, which Foobar.__getattribute__
dynamically attaches to the selected instance:
('real', <__main__.Foobar object at 0x02EF134C>)
^^^^^^^^^^
IOW, a plain callable has __get__ and gets bound to the instance,
whereas a bound method doesn't have __get__ any more, so it gets
retrieved as a plain attribute. BTW, to get an ordinary function call
for a function attribute of a Foobar instance, you'd have to
eliminate the function's __get__ effect one way or another,
e.g. staticmethod (which really wraps the function with a descriptor,
substituting its own __get__, which Foobar.__getattribute__ uses transparently)
>>> def sm(firstarg='sm first arg', *args): return firstarg, args ...
>>> g.sm = staticmethod(sm)
>>> g.sm() ('sm first arg', ())
>>> g.sm
>>> g.__dict__['sm'].__get__
>>> g.__dict__['sm'].__get__(g)
<function sm at 0x02EE8E9C>
Regards,
Bengt Richter