Adding modified methods from another class without subclassing
Steven D'Aprano
steve+comp.lang.python at pearwood.info
Tue Aug 23 03:25:22 EDT 2011
On Mon, 22 Aug 2011 11:08 pm John O'Hagan wrote:
> On Mon, 22 Aug 2011 15:27:36 +1000
> Steven D'Aprano <steve+comp.lang.python at pearwood.info> wrote:
[...]
>> # Untested
>> class MySeq(object):
>> methods_to_delegate = ('__getitem__', '__len__', ...)
>> pitches = ... # make sure pitches is defined
>> def __getattr__(self, name):
>> if name in self.__class__.methods_to_delegate:
>> return getattr(self.pitches, name)
>> return super(MySeq, object).__getattr__(self, name)
>> # will likely raise AttributeError
>
> Thanks, this looks promising. I didn't know about __getattr__ or
> delegation. This example doesn't seem to work as is for special methods
> beginning with "__" (e.g.: "TypeError: object of type 'MyList' has no
> len()"). It seems that __getattr__ is not called for special methods.
Ah yes, that would be a problem.
This recipe may help.
http://code.activestate.com/recipes/252151-generalized-delegates-and-proxies/
> Also, it doesn't immediately suggest to me a way of modifying method calls
> (maybe __setattr__?).
What do you mean, "modifying method calls"?
__getattr__ doesn't know whether the method retrieved modifies the instance
or not. That's irrelevant.
__setattr__ is called when you say
instance.attribute = value
> But it's certainly a neater way to get methods to
> operate on the attribute. I'm looking into it, and delegation generally.
>
> However, I don't understand what the super call is doing. If the method
> isn't delegated, shouldn't it just fall back to getattr(self, name)?
getattr(self, name) will just call self.__getattr__(name) again, which will
call getattr, and so on... leading to RecursionError.
--
Steven
More information about the Python-list
mailing list