is decorator the right thing to use?

Dmitry S. Makovey dmitry at athabascau.ca
Thu Sep 25 11:41:04 EDT 2008


Diez B. Roggisch wrote:

> Dmitry S. Makovey schrieb:
>> Dmitry S. Makovey wrote:
>>> In my real-life case A is a proxy to B, C and D instances/objects, not
>>> just one.
>> 
>> forgot to mention that above would mean that I need to have more than one
>> decorator function like AproxyB, AproxyC and AproxyD or make Aproxy
>> smarter about which property of A has instance of which class etc.
> 
> __getattr__?

see, in your code you're assuming that there's only 1 property ( 'b' )
inside of A that needs proxying. In reality I have several. So in your code
self._delegate should be at least a tupple or a list. Plus what you're
doing - you just promiscuously passing any method not found in Proxy to
self._delegate which is not what I need as I need to pass only a subset of
calls, so now your code needs to acquire dictionary of "allowed" calls, and
go over all self._delegates to find if any one has it which is not
efficient since there IS a 1:1 mapping of A::method -> B::method so lookups
shouldn't be necessary IMO (for performance reasons).

> class Proxy(object):
> 
> 
>      def __init__(self, delegate):
>          self._delegate = delegate
> 
> 
>      def __getattr__(self, attr):
>          v = getattr(self._delegate, attr)
>          if callable(v):
>             class CallInterceptor(object):
>                   def __init__(self, f):
>                       self._f = f
> 
>                   def __call__(self, *args, **kwargs):
>                       print "Called " + str(self._f) + " with " +
> str(args) + str(kwargs)
>                       return self._f(*args, **kwargs)
>             return CallInterceptor(v)
>          return v

> Decorators have *nothing* to do with this. They are syntactic sugar for
> def foo(...):
>      ...
> foo = a_decorator(foo)

exactly. and in my case they would've simplified code reading/maintenance.
However introduced "tight coupling" (A knows about B and be should know
about A) is something that worries me and I'm trying to figure out if there
is another way to use decorators for my scenario or is there another way of
achieving the same thing without using decorators and without bloating up
the code with alternative solution. 

Another way could be to use Metaclass to populate class with method upon
declaration but that presents quite a bit of "special" cruft which is more
than I have to do with decorators :) (but maybe it's all *necessary* ? )




More information about the Python-list mailing list