Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #29166 > unrolled thread

Re: Decorators not worth the effort

Started byJean-Michel Pichavant <jeanmichel@sequans.com>
First post2012-09-14 15:22 +0200
Last post2012-09-14 15:19 +0000
Articles 2 — 2 participants

Back to article view | Back to comp.lang.python


Contents

  Re: Decorators not worth the effort Jean-Michel Pichavant <jeanmichel@sequans.com> - 2012-09-14 15:22 +0200
    Re: Decorators not worth the effort Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-09-14 15:19 +0000

#29166 — Re: Decorators not worth the effort

FromJean-Michel Pichavant <jeanmichel@sequans.com>
Date2012-09-14 15:22 +0200
SubjectRe: Decorators not worth the effort
Message-ID<mailman.703.1347628931.27098.python-list@python.org>

----- Original Message -----
> Jean-Michel Pichavant <jeanmichel@sequans.com> wrote:
> 
> > I wrote the following one, used to decorate any function that
> > access
> > an equipment, it raises an exception when the timeout expires. The
> > timeout is adapted to the platform, ASIC of FPGA so people don't
> > need
> > to specify everytime one timeout per platform.
> > 
> > In the end it would replace
> > 
> > def boot(self, timeout=15):
> >     if FPGA:
> >         self.sendCmd("bootMe", timeout=timeout*3)
> >     else:
> >         self.sendCmd("bootMe", timeout=timeout)
> > 
> > with
> > 
> > @timeout(15)
> > def boot(self, timeout=None):
> >     self.sendCmd("bootMe", timeout)
> > 
> > I wrote a nice documentation with sphinx to explain this, how to
> > use
> > it, how it can improve code. After spending hours on the decorator
> > +
> > doc, feedback from my colleagues : What the F... !!
> > 
> 
> I'd agree with your colleagues. How are you going to ensure that all
> relevant functions are decorated and yet no decorated function ever
> calls another decorated one?
> 
> From the code you posted it would seem appropriate that the
> adjustment
> of the timeout parameter happen in the `sendCmd()` method itself and
> nowhere else. Alternatively use named values for different categories
> of
> timeouts and adjust them on startup so instead of a default of
> `timeout=
> 15` you would have a default `timeout=MEDIUM_TIMEOUT` or whatever
> name
> is appropriate.
> 
> --
> Duncan Booth http://kupuguy.blogspot.com
> --
> http://mail.python.org/mailman/listinfo/python-list

All functions set different timeout values, I cannot use a DEFAULT_VALUE.
All functions are design in the same way:

def doSomeAction(self, timeout):
    preprocess()
    self.sendCmd('relatedAction', timeout) # send the command to the device CLI interface
    postprocess()

Ultimately, the goal is to have something like

@timeout(2)
def doAction1

@timeout(4)
def doAction2

@timeout(12)
def doAction3

and so on... (1 second is important, because there's a platform I remove from my example, didn't want to advertise publicly tech used by the company, that runs 1000 times slower)

Additionally, the multiple check I run within the decorator is for consistency check and argument checking. I though it was a good idea because our python engine is used by a dozen of engineers to control equipment, and any misuse of this new decorator would lead to badly configured timeouts with heavy consequences on the test sessions. Sometimes a RTFM is not enough, when you need to make this work, you slip on your Batman costume like Steven suggested, and you save the day (or so I though :) ) by raising nice exceptions about missing keyword argument.

But let's forget about my poor example, I end up describing my life which is pretty pointless.

Here's Steven example:

# Untested!
def timeout(t=15):
    # Decorator factory. Return a decorator to actually do the work.
    if FPGA:
        t *= 3
    def decorator(func):
        @functools.wraps(func)
        def inner(self, timeout):
            self.sendCmd("bootMe", timeout=t)
        return inner
    return decorator

I can assure you, that for some python users, it's is not easy to understand what it does, this function returning a function which returns another (wrapped) function. It requires some effort.

JM

[toc] | [next] | [standalone]


#29174

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2012-09-14 15:19 +0000
Message-ID<50534b1e$0$29981$c3e8da3$5496439d@news.astraweb.com>
In reply to#29166
On Fri, 14 Sep 2012 15:22:26 +0200, Jean-Michel Pichavant wrote:

> Here's Steven example:
> 
> # Untested!
> def timeout(t=15):
>     # Decorator factory. Return a decorator to actually do the work. if
>     FPGA:
>         t *= 3
>     def decorator(func):
>         @functools.wraps(func)
>         def inner(self, timeout):
>             self.sendCmd("bootMe", timeout=t)
>         return inner
>     return decorator
> 
> I can assure you, that for some python users, it's is not easy to
> understand what it does, this function returning a function which
> returns another (wrapped) function. It requires some effort.

Oh I agree. So does learning to tie your shoe-laces, learning to cook, 
and learning to drive.

Learning to be a world-class chess master takes a lot of effort. Learning 
about decorators does not.


-- 
Steven

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web