Bryan wrote:
Nick Coghlan wrote:

Bryan wrote:

i'm also curious if it's possible to write this recipe using the new class style for the Deffered class. it appears you can nolonger delegate all attributes including special methods to the contained object by using the __getattr__ or the new __getattribute__ methods. does anyone know how to port this recipe to the new class style?



Override __getattribute__. I don't know why you think it doesn't let you override all attribute accesses, as that's exactly what it is for.


Cheers,
Nick.


here's an example. __getattribute__ gets called for x but not for the special method __add__. and the __str__ method was found in the base class object which printed the memory location, but didn't call __getattribute__. so __getattribute__ cannot be used to capture special methods and delegate them to an encapsulated object. this is why i'm asking what the technique using new classes would be for this recipe.

Hmm, good point. I now have a vague idea why it happens that way, too (essentially, it appears the setting of the magic methods causes the interpreter to be notified that the object has a Python-defined method to call. With only __getattribute__ defined, that notification doesn't happen for all of the other magic methods).


This actually makes sense - otherwise how would the method which implements __getattribute__ be retrieved?

Similarly, in the existing recipe, none of __init__, __call__, __coerce__ or __getattr__ are delegated - the behaviour is actually consistent for all magic methods (I'm curious how the existing recipe actually works - it seems the use of "self.runfunc" in __call__ should get delegated. It obviously isn't, though).

Something like the following might work (I haven't tested it though):

  class Deferred(object):
    ...

  def lookup_magic(f_name):
    def new_f(self, *args, **kwargs):
      return getattr(self, f_name)(*args, **kwargs)
    return new_f

  func_list = ['__add__', '__radd__', ...]
  for f_name in func_list:
    setattr(Deferred, f_name) = lookup_magic(f_name)

A metaclass may actually provide a cleaner solution, but I'm not quite sure where to start with that.

Cheers,
Nick.

--
Nick Coghlan   |   [EMAIL PROTECTED]   |   Brisbane, Australia
---------------------------------------------------------------
            http://boredomandlaziness.skystorm.net
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to