__getattribute__ and methods proxying
Thomas Jollans
thomas at jollans.com
Sat Jun 12 16:42:07 EDT 2010
On 06/12/2010 09:59 PM, Giampaolo RodolĂ wrote:
> 2010/6/12 David Zaslavsky <diazona at ellipsix.net>:
>> Hi,
>>
>> The problem is that when you make this call:
>>> proc.cmdline()
>> there are really two steps involved. First you are accessing proc.cmdline,
>> then you are calling it. You could think of it as this:
>> func = proc.cmdline
>> func()
>> __getattribute__ is able to modify how the first step works, but not the
>> second. And it is the second step where the OSError gets raised.
>>
>> You could get around this by returning a wrapper function from
>> __getattribute__, something like this I think:
>>
>> def __getattribute__(self, name):
>> f = object.__getattribute__(self, name)
>> # here you should really check whether it's a function
>> def wrapper(self, *args, **kwargs)
>> print "here 1!"
>> try:
>> f(*args, **kwargs)
>> except OSError, err:
>> print "here 2!"
>> if err.errno == errno.ESRCH:
>> raise NoSuchProcess
>> if err.errno == errno.EPERM:
>> raise AccessDenied
>> return wrapper
>>
>> That way "func" gets set to the wrapper function, which will handle your
>> exception as you want.
>>
>> :) David
>> --
>> http://mail.python.org/mailman/listinfo/python-list
>>
>
> Clear, thanks.
> Isn't there a prettier/common way to do this?
> A __methodcall__(self, method_obj) special method or something? Has
> something like that ever been proposed for inclusion?
There is no such thing as a method call in Python. There is attribute
access, and there is calling objects. You could, of course, create a
__methodcall__ method. That might look something like this:
class with_methodcall_trick(object):
def __methodcall__(self, method, *args, **kwa):
raise NotImplementedError("__methodcall__ must be overriden")
def __getattribute__(self, name):
obj = super(with_methodcall_trick, self).__getattribute__(name)
if callable(obj):
wrapper = functools.partial(self.__methodcall__, obj)
functools.update_wrapper(wrapper, obj)
return wrapper
else:
return wrapped
More information about the Python-list
mailing list