By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,442 Members | 1,311 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,442 IT Pros & Developers. It's quick & easy.

deferred decorator

P: n/a
i was intrigued with a recently posted cookbook recipe which implements deferred
results with decorators:

http://aspn.activestate.com/ASPN/Coo.../Recipe/355651

the problem i see with this recipe is that the author only tested his code by
printing the values which causes __getattr__ to be called with '__str__' and
work correctly. but, if you were to remove the print statements and just do a v
+ v, __getattr__ won't get called as he expected and the join will never happen.
i think by making __coerce__ as smart as __getattr__ this recipe would work.
can someone validate that i'm correct in what i'm saying?

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?

thanks,

bryan
Jul 18 '05 #1
Share this Question
Share on Google+
3 Replies


P: n/a
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.

--
Nick Coghlan | nc******@email.com | Brisbane, Australia
---------------------------------------------------------------
http://boredomandlaziness.skystorm.net
Jul 18 '05 #2

P: n/a
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.

class Foo(object): .... def __getattribute__(self, name):
.... raise AttributeError('__getattribute__ is called')
.... f = Foo()
f.x() Traceback (most recent call last):
File "<interactive input>", line 1, in ?
File "<interactive input>", line 3, in __getattribute__
AttributeError: __getattribute__ is called f + f Traceback (most recent call last):
File "<interactive input>", line 1, in ?
TypeError: unsupported operand type(s) for +: 'Foo' and 'Foo' str(f)

'<__main__.Foo object at 0x0118AD10>'
Jul 18 '05 #3

P: n/a
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 | nc******@email.com | Brisbane, Australia
---------------------------------------------------------------
http://boredomandlaziness.skystorm.net
Jul 18 '05 #4

This discussion thread is closed

Replies have been disabled for this discussion.