Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #29057 > unrolled thread
| Started by | Jean-Michel Pichavant <jeanmichel@sequans.com> |
|---|---|
| First post | 2012-09-13 19:54 +0200 |
| Last post | 2012-09-15 08:31 +0200 |
| Articles | 20 on this page of 23 — 12 participants |
Back to article view | Back to comp.lang.python
Re: Python presentations Jean-Michel Pichavant <jeanmichel@sequans.com> - 2012-09-13 19:54 +0200
Re: Python presentations Alister <alister.ware@ntlworld.com> - 2012-09-13 18:18 +0000
Decorators not worth the effort alex23 <wuwei23@gmail.com> - 2012-09-13 18:58 -0700
Re: Decorators not worth the effort Cameron Simpson <cs@zip.com.au> - 2012-09-14 12:12 +1000
Re: Decorators not worth the effort alex23 <wuwei23@gmail.com> - 2012-09-13 20:25 -0700
Re: Decorators not worth the effort Dieter Maurer <dieter@handshake.de> - 2012-09-14 08:40 +0200
Re: Decorators not worth the effort Terry Reedy <tjreedy@udel.edu> - 2012-09-14 16:29 -0400
Re: Decorators not worth the effort Thomas Rachel <nutznetz-0c1b6768-bfa9-48d5-a470-7603bd3aa915@spamschutz.glglgl.de> - 2012-09-15 09:13 +0200
Re: Decorators not worth the effort alex23 <wuwei23@gmail.com> - 2012-09-16 17:38 -0700
Re: Decorators not worth the effort Terry Reedy <tjreedy@udel.edu> - 2012-09-14 16:31 -0400
Re: Decorators not worth the effort Terry Reedy <tjreedy@udel.edu> - 2012-09-14 16:37 -0400
Re: Decorators not worth the effort 88888 Dihedral <dihedral88888@googlemail.com> - 2012-09-18 16:47 -0700
Re: Decorators not worth the effort 88888 Dihedral <dihedral88888@googlemail.com> - 2012-09-18 16:47 -0700
Re: Decorators not worth the effort Terry Reedy <tjreedy@udel.edu> - 2012-09-14 16:33 -0400
Re: Decorators not worth the effort Ian Kelly <ian.g.kelly@gmail.com> - 2012-09-14 15:16 -0600
Re: Decorators not worth the effort Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-09-14 23:39 +0000
Re: Decorators not worth the effort 88888 Dihedral <dihedral88888@googlemail.com> - 2012-09-15 02:45 -0700
Re: Decorators not worth the effort Dwight Hutto <dwightdhutto@gmail.com> - 2012-09-15 06:04 -0400
Re: Decorators not worth the effort 88888 Dihedral <dihedral88888@googlemail.com> - 2012-09-15 07:18 -0700
Re: Decorators not worth the effort Thomas Rachel <nutznetz-0c1b6768-bfa9-48d5-a470-7603bd3aa915@spamschutz.glglgl.de> - 2012-09-18 14:16 +0200
Re: Decorators not worth the effort 88888 Dihedral <dihedral88888@googlemail.com> - 2012-09-15 07:18 -0700
Re: Decorators not worth the effort Dwight Hutto <dwightdhutto@gmail.com> - 2012-09-14 23:42 -0400
Re: Decorators not worth the effort "Dieter Maurer" <dieter@handshake.de> - 2012-09-15 08:31 +0200
Page 1 of 2 [1] 2 Next page →
| From | Jean-Michel Pichavant <jeanmichel@sequans.com> |
|---|---|
| Date | 2012-09-13 19:54 +0200 |
| Subject | Re: Python presentations |
| Message-ID | <mailman.623.1347558870.27098.python-list@python.org> |
----- Original Message ----- > I have to give a couple of Python presentations in the next weeks, > and > I'm still thinking what is the best approach. > > In one presentation for example I will present decorators and context > managers, and my biggest doubt is how much I should show and explain > in > slides and how much in an interactive way (with ipython for example). > > For my experience if I only see code in slides I tend not to believe > that it works somehow, but also only looking at someone typing can be > hard to follow and understand what is going on.. > > So maybe I should do first slides and then interactive demo, or the > other way around, showing first how everything works and then > explaining > the code with slides. > > What do you think work best in general? > -- > http://mail.python.org/mailman/listinfo/python-list > I don't like decorators, I think they're not worth the mental effort. So if I were to intend to your presentation, I'd really like you to start demonstrating how decorators are life savers, or with less emphasis, how they can be worth the effort and make me regret all these years without decorators. Some features in python have this WoW! effect, try to trigger it in front of your audience, that should really help them focus on the subject and be interested in your presentation. Also try to keep the presentation interactive by asking questions to your audience (unless some of them are already participating), otherwise people will be snoring or texting after 20 minutes. I think the key for a presentation is to make people interested in the subject and make them realize they can benefit from what you're presenting. Everyone can then google 'python decorators' for the technical and boring details. I must add that I'm not en experienced presenter, so take my advices for what they're worth (hmm not sure about this grammatical construct :-/ ) JM
[toc] | [next] | [standalone]
| From | Alister <alister.ware@ntlworld.com> |
|---|---|
| Date | 2012-09-13 18:18 +0000 |
| Message-ID | <Krp4s.222258$5o4.107388@fx23.am4> |
| In reply to | #29057 |
> Also try to keep the presentation interactive by asking questions to > your audience (unless some of them are already participating), otherwise > people will be snoring or texting after 20 minutes. That is a v good suggestion. the best presentation I ever attended was one on using an emergency life raft presented by a member of the local sailing club (I was a scuba diver at the time & our club was lending them some pool time) The whole presentation consisted of a sequence of questions fired at the audience to get them to think the problem trough & arrive at the correct sequence of events. Genius -- The best prophet of the future is the past.
[toc] | [prev] | [next] | [standalone]
| From | alex23 <wuwei23@gmail.com> |
|---|---|
| Date | 2012-09-13 18:58 -0700 |
| Subject | Decorators not worth the effort |
| Message-ID | <f7e2ec78-2c4a-402e-9a90-6cf0e7e55a54@c8g2000pbe.googlegroups.com> |
| In reply to | #29057 |
On Sep 14, 3:54 am, Jean-Michel Pichavant <jeanmic...@sequans.com> wrote: > I don't like decorators, I think they're not worth the mental effort. Because passing a function to a function is a huge cognitive burden?
[toc] | [prev] | [next] | [standalone]
| From | Cameron Simpson <cs@zip.com.au> |
|---|---|
| Date | 2012-09-14 12:12 +1000 |
| Subject | Re: Decorators not worth the effort |
| Message-ID | <mailman.658.1347588736.27098.python-list@python.org> |
| In reply to | #29097 |
On 13Sep2012 18:58, alex23 <wuwei23@gmail.com> wrote: | On Sep 14, 3:54 am, Jean-Michel Pichavant <jeanmic...@sequans.com> | wrote: | > I don't like decorators, I think they're not worth the mental effort. | | Because passing a function to a function is a huge cognitive burden? It is for me when I'm _writing_ the decorator:-) But if I get it right and name it well I find it dramaticly _decreases_ the cognitive burden of the code using the decorator... -- Cameron Simpson <cs@zip.com.au> Observing the first balloon ascent in Paris, [Ben] Franklin heard a scoffer ask, "What good is it?" He spoke for a generation of scientists in his retort, "What good is a newly born infant?" - John F. Kasson
[toc] | [prev] | [next] | [standalone]
| From | alex23 <wuwei23@gmail.com> |
|---|---|
| Date | 2012-09-13 20:25 -0700 |
| Subject | Re: Decorators not worth the effort |
| Message-ID | <50d83c64-033e-498f-a7a4-bafb2f322807@k13g2000pbq.googlegroups.com> |
| In reply to | #29101 |
On Sep 14, 12:12 pm, Cameron Simpson <c...@zip.com.au> wrote: > On 13Sep2012 18:58, alex23 <wuwe...@gmail.com> wrote: > | On Sep 14, 3:54 am, Jean-Michel Pichavant <jeanmic...@sequans.com>| wrote: > | > I don't like decorators, I think they're not worth the mental effort. > | > | Because passing a function to a function is a huge cognitive burden? > > It is for me when I'm _writing_ the decorator:-) But if I get it right > and name it well I find it dramaticly _decreases_ the cognitive burden > of the code using the decorator... Okay, I will concede that point :)
[toc] | [prev] | [next] | [standalone]
| From | Dieter Maurer <dieter@handshake.de> |
|---|---|
| Date | 2012-09-14 08:40 +0200 |
| Subject | Re: Decorators not worth the effort |
| Message-ID | <mailman.678.1347604877.27098.python-list@python.org> |
| In reply to | #29097 |
> On Sep 14, 3:54 am, Jean-Michel Pichavant <jeanmic...@sequans.com> > wrote: >> I don't like decorators, I think they're not worth the mental effort. Fine. I like them because they can vastly improve reusability and drastically reduce redundancies (which I hate). Improved reusability and reduced redundancies can make applications more readable, easier to maintain and faster to develop.
[toc] | [prev] | [next] | [standalone]
| From | Terry Reedy <tjreedy@udel.edu> |
|---|---|
| Date | 2012-09-14 16:29 -0400 |
| Subject | Re: Decorators not worth the effort |
| Message-ID | <mailman.716.1347654606.27098.python-list@python.org> |
| In reply to | #29097 |
On 9/13/2012 10:12 PM, Cameron Simpson wrote:
> On 13Sep2012 18:58, alex23 <wuwei23@gmail.com> wrote:
> | On Sep 14, 3:54 am, Jean-Michel Pichavant <jeanmic...@sequans.com>
> | wrote:
> | > I don't like decorators, I think they're not worth the mental effort.
> |
> | Because passing a function to a function is a huge cognitive burden?
For parameterized decorators, there is extra cognitive burden. See below.
> It is for me when I'm _writing_ the decorator:-) But if I get it right
> and name it well I find it dramaticly _decreases_ the cognitive burden
> of the code using the decorator...
For a simple, unparameterized wrapper, the difficulty is entirely in the
wrapper maker. It must define the final wrapper as a nested function and
return it*. It is irrelevant whether the wrapper maker is used with
pre-def decorator syntax or with an explicit post-def call.
*I am here ignoring the option of a class with __call__ method.
For a parameterized wrapper, using decorator syntax requires passing the
parameter(s) first and the function to be wrapped later. This requires
currying the wrapper maker with double nesting. The nesting order may
seem inside-out to some. For most people, this is extra work compared to
writing a wrapper that accepts the function and parameters together and
only has a single level of nesting.
In other words
def make_wrapper(func, param):
def wrapper(*args, **kwds):
for i in range(param):
func(*args, **kwds)
return wrapper
def f(x): print(x)
f = make_wrapper(f, 2)
f('simple')
# is simpler, at least for some people, than the following
# which does essentially the same thing.
def make_outer(param):
def make_inner(func):
def wrapper(*args, **kwds):
for i in range(param):
func(*args, **kwds)
return wrapper
return make_inner
@make_outer(2)
def f(x): print(x)
f('complex')
Is the gain of not repeating the wrapped function name twice in the
post-def wrapping call, and the gain of knowing the function will be
wrapped before reading the def, worth the pain of currying the wrapper
maker?
--
Terry Jan Reedy
[toc] | [prev] | [next] | [standalone]
| From | Thomas Rachel <nutznetz-0c1b6768-bfa9-48d5-a470-7603bd3aa915@spamschutz.glglgl.de> |
|---|---|
| Date | 2012-09-15 09:13 +0200 |
| Subject | Re: Decorators not worth the effort |
| Message-ID | <k319qh$4n4$1@r03.glglgl.gl> |
| In reply to | #29184 |
[Sorry, my Firefox destroyed the indent...
Am 14.09.2012 22:29 schrieb Terry Reedy:
> In other words
>
> def make_wrapper(func, param):
> def wrapper(*args, **kwds):
> for i in range(param):
> func(*args, **kwds)
> return wrapper
>
> def f(x): print(x)
> f = make_wrapper(f, 2)
> f('simple')
>
> # is simpler, at least for some people, than the following
> # which does essentially the same thing.
>
> def make_outer(param):
> def make_inner(func):
> def wrapper(*args, **kwds):
> for i in range(param):
> func(*args, **kwds)
> return wrapper
> return make_inner
>
> @make_outer(2)
> def f(x): print(x)
> f('complex')
For this case, my mydeco.py which I use quite often contains a
def indirdeco(ind):
# Update both the outer as well as the inner wrapper.
# If we knew the inner one was to be updated with something
# from *a, **k, we could do it. But not this way...
@functools.wraps(ind)
def outer(*a, **k):
@functools.wraps(ind)
def inner(f):
return ind(f, *a, **k)
return inner
return outer
so I can do
@indirdeco
def make_wrapper(func, param):
@functools.wraps(func)
def wrapper(*args, **kwds):
for i in range(param):
func(*args, **kwds)
return wrapper
and then nevertheless
@make_wrapper(2)
def f(x): print(x)
BTW, I also have a "meta-decorator" for the other direction:
def wrapfunction(mighty):
"""Wrap a function taking (f, *a, **k) and replace it with a
function taking (f) and returning a function taking (*a, **k) which
calls our decorated function.
Other direction than indirdeco."""
@functools.wraps(mighty)
def wrapped_outer(inner):
@functools.wraps(inner)
def wrapped_inner(*a, **k):
return mighty(inner, *a, **k)
wrapped_inner.func = inner # keep the wrapped function
wrapped_inner.wrapper = mighty # and the replacement
return wrapped_inner
wrapped_outer.func = mighty # keep this as well
return wrapped_outer
With this, a
@wrapfunction
def twice(func, *a, **k):
return func(*a, **k), func(*a, **k)
can be used with
@twice
def f(x): print (x); return x
very nicely.
Thomas
[toc] | [prev] | [next] | [standalone]
| From | alex23 <wuwei23@gmail.com> |
|---|---|
| Date | 2012-09-16 17:38 -0700 |
| Subject | Re: Decorators not worth the effort |
| Message-ID | <f6cda94f-83ee-4110-832f-1f74e21c58ee@q9g2000pbo.googlegroups.com> |
| In reply to | #29184 |
On Sep 15, 6:30 am, Terry Reedy <tjre...@udel.edu> wrote: > > On 13Sep2012 18:58, alex23 <wuwe...@gmail.com> wrote: > > | On Sep 14, 3:54 am, Jean-Michel Pichavant <jeanmic...@sequans.com> > > | wrote: > > | > I don't like decorators, I think they're not worth the mental effort. > > | > > | Because passing a function to a function is a huge cognitive burden? > > For parameterized decorators, there is extra cognitive burden. See below. I do regret my initial criticism, for exactly this reason.
[toc] | [prev] | [next] | [standalone]
| From | Terry Reedy <tjreedy@udel.edu> |
|---|---|
| Date | 2012-09-14 16:31 -0400 |
| Subject | Re: Decorators not worth the effort |
| Message-ID | <mailman.717.1347654906.27098.python-list@python.org> |
| In reply to | #29097 |
On 9/14/2012 5:28 AM, Jean-Michel Pichavant wrote: > Decorators are very popular so I kinda already know that the fault is mine. Now to the reason why I have troubles writing them, I don't know. Every time I did use decorators, I spent way too much time writing it (and debugging it). -- Terry Jan Reedy
[toc] | [prev] | [next] | [standalone]
| From | Terry Reedy <tjreedy@udel.edu> |
|---|---|
| Date | 2012-09-14 16:37 -0400 |
| Subject | Re: Decorators not worth the effort |
| Message-ID | <mailman.718.1347655202.27098.python-list@python.org> |
| In reply to | #29097 |
2nd try, hit send button by mistake before On 9/14/2012 5:28 AM, Jean-Michel Pichavant wrote: > Decorators are very popular so I kinda already know that the fault is > mine. Now to the reason why I have troubles writing them, I don't > know. Every time I did use decorators, I spent way too much time > writing it (and debugging it). You are writing parameterized decorators, which require inverted currying of the wrapper maker. Perhaps that is why you have trouble. As I showed in response to Cameron, it may be easier to avoid that by using a traditional post-def wrapping call instead of decorator syntax. -- Terry Jan Reedy
[toc] | [prev] | [next] | [standalone]
| From | 88888 Dihedral <dihedral88888@googlemail.com> |
|---|---|
| Date | 2012-09-18 16:47 -0700 |
| Subject | Re: Decorators not worth the effort |
| Message-ID | <5995c4c4-42f0-4af1-9154-eb3378230cf9@googlegroups.com> |
| In reply to | #29186 |
Terry Reedy於 2012年9月15日星期六UTC+8上午4時40分32秒寫道:
> 2nd try, hit send button by mistake before
>
>
>
> On 9/14/2012 5:28 AM, Jean-Michel Pichavant wrote:
>
>
>
> > Decorators are very popular so I kinda already know that the fault is
>
> > mine. Now to the reason why I have troubles writing them, I don't
>
> > know. Every time I did use decorators, I spent way too much time
>
> > writing it (and debugging it).
>
>
>
> You are writing parameterized decorators, which require inverted
>
> currying of the wrapper maker. Perhaps that is why you have trouble. As
>
> I showed in response to Cameron, it may be easier to avoid that by using
>
> a traditional post-def wrapping call instead of decorator syntax.
>
>
>
> --
>
> Terry Jan Reedy
I'll give another example to show the decorators in python in
versions above 2.4 .
# a general function with the variable input : def fname( *argc, **argn)
# a deco is a mapping from an input funtion to another function
def deco( fn, *list_in, **dict_in): # use list_in and dict_in to modify fn
""" deco wrapper """ # deco.__doc__
#print list_in, dict_in, " in the deco"
def wrapper( fn, *argc, **argan): # to be returned as a function
# do things one wants before calling fn
result=fn(*argc, **argn) # call the original, save the result
# do things after calling fn
return result
# enhance the wrapper and get info of fn
wrapper.__doc__=fn.__doc__
# enhance wrapper with result, fn, list_in, dict_in
#....
return wrapper
def f1():
""" doc of f1"""
print "inside f1"
f2=deco(f1, 2,3,4,5,6, MSG="deco f1 to f2")
f2() # invoke the decorated function from f1
# For a deco maps a deco to another deco can be done similarly
[toc] | [prev] | [next] | [standalone]
| From | 88888 Dihedral <dihedral88888@googlemail.com> |
|---|---|
| Date | 2012-09-18 16:47 -0700 |
| Subject | Re: Decorators not worth the effort |
| Message-ID | <mailman.894.1348012073.27098.python-list@python.org> |
| In reply to | #29186 |
Terry Reedy於 2012年9月15日星期六UTC+8上午4時40分32秒寫道:
> 2nd try, hit send button by mistake before
>
>
>
> On 9/14/2012 5:28 AM, Jean-Michel Pichavant wrote:
>
>
>
> > Decorators are very popular so I kinda already know that the fault is
>
> > mine. Now to the reason why I have troubles writing them, I don't
>
> > know. Every time I did use decorators, I spent way too much time
>
> > writing it (and debugging it).
>
>
>
> You are writing parameterized decorators, which require inverted
>
> currying of the wrapper maker. Perhaps that is why you have trouble. As
>
> I showed in response to Cameron, it may be easier to avoid that by using
>
> a traditional post-def wrapping call instead of decorator syntax.
>
>
>
> --
>
> Terry Jan Reedy
I'll give another example to show the decorators in python in
versions above 2.4 .
# a general function with the variable input : def fname( *argc, **argn)
# a deco is a mapping from an input funtion to another function
def deco( fn, *list_in, **dict_in): # use list_in and dict_in to modify fn
""" deco wrapper """ # deco.__doc__
#print list_in, dict_in, " in the deco"
def wrapper( fn, *argc, **argan): # to be returned as a function
# do things one wants before calling fn
result=fn(*argc, **argn) # call the original, save the result
# do things after calling fn
return result
# enhance the wrapper and get info of fn
wrapper.__doc__=fn.__doc__
# enhance wrapper with result, fn, list_in, dict_in
#....
return wrapper
def f1():
""" doc of f1"""
print "inside f1"
f2=deco(f1, 2,3,4,5,6, MSG="deco f1 to f2")
f2() # invoke the decorated function from f1
# For a deco maps a deco to another deco can be done similarly
[toc] | [prev] | [next] | [standalone]
| From | Terry Reedy <tjreedy@udel.edu> |
|---|---|
| Date | 2012-09-14 16:33 -0400 |
| Subject | Re: Decorators not worth the effort |
| Message-ID | <mailman.720.1347655802.27098.python-list@python.org> |
| In reply to | #29097 |
On 9/14/2012 4:29 PM, Terry Reedy wrote:
> On 9/13/2012 10:12 PM, Cameron Simpson wrote:
>> On 13Sep2012 18:58, alex23 <wuwei23@gmail.com> wrote:
>> | On Sep 14, 3:54 am, Jean-Michel Pichavant <jeanmic...@sequans.com>
>> | wrote:
>> | > I don't like decorators, I think they're not worth the mental effort.
>> |
>> | Because passing a function to a function is a huge cognitive burden?
>
> For parameterized decorators, there is extra cognitive burden. See below.
>
>
>> It is for me when I'm _writing_ the decorator:-) But if I get it right
>> and name it well I find it dramaticly _decreases_ the cognitive burden
>> of the code using the decorator...
>
> For a simple, unparameterized wrapper, the difficulty is entirely in the
> wrapper maker. It must define the final wrapper as a nested function and
> return it*. It is irrelevant whether the wrapper maker is used with
> pre-def decorator syntax or with an explicit post-def call.
>
> *I am here ignoring the option of a class with __call__ method.
>
> For a parameterized wrapper, using decorator syntax requires passing the
> parameter(s) first and the function to be wrapped later. This requires
> currying the wrapper maker with double nesting. The nesting order may
> seem inside-out to some. For most people, this is extra work compared to
> writing a wrapper that accepts the function and parameters together and
> only has a single level of nesting.
>
> In other words
>
> def make_wrapper(func, param):
> def wrapper(*args, **kwds):
> for i in range(param):
> func(*args, **kwds)
> return wrapper
>
> def f(x): print(x)
> f = make_wrapper(f, 2)
> f('simple')
>
> # is simpler, at least for some people, than the following
> # which does essentially the same thing.
>
> def make_outer(param):
> def make_inner(func):
> def wrapper(*args, **kwds):
> for i in range(param):
> func(*args, **kwds)
> return wrapper
> return make_inner
>
> @make_outer(2)
> def f(x): print(x)
> f('complex')
>
> Is the gain of not repeating the wrapped function name twice in the
> post-def wrapping call, and the gain of knowing the function will be
> wrapped before reading the def, worth the pain of currying the wrapper
> maker?
>
--
Terry Jan Reedy
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2012-09-14 15:16 -0600 |
| Subject | Re: Decorators not worth the effort |
| Message-ID | <mailman.722.1347657439.27098.python-list@python.org> |
| In reply to | #29097 |
On Fri, Sep 14, 2012 at 2:29 PM, Terry Reedy <tjreedy@udel.edu> wrote:
> For a simple, unparameterized wrapper, the difficulty is entirely in the
> wrapper maker. It must define the final wrapper as a nested function and
> return it*. It is irrelevant whether the wrapper maker is used with pre-def
> decorator syntax or with an explicit post-def call.
>
> *I am here ignoring the option of a class with __call__ method.
>
> For a parameterized wrapper, using decorator syntax requires passing the
> parameter(s) first and the function to be wrapped later. This requires
> currying the wrapper maker with double nesting. The nesting order may seem
> inside-out to some. For most people, this is extra work compared to writing
> a wrapper that accepts the function and parameters together and only has a
> single level of nesting.
>
> In other words
>
> def make_wrapper(func, param):
> def wrapper(*args, **kwds):
> for i in range(param):
> func(*args, **kwds)
> return wrapper
>
> def f(x): print(x)
> f = make_wrapper(f, 2)
> f('simple')
>
> # is simpler, at least for some people, than the following
> # which does essentially the same thing.
>
> def make_outer(param):
> def make_inner(func):
> def wrapper(*args, **kwds):
> for i in range(param):
> func(*args, **kwds)
> return wrapper
> return make_inner
>
> @make_outer(2)
> def f(x): print(x)
> f('complex')
>
> Is the gain of not repeating the wrapped function name twice in the post-def
> wrapping call, and the gain of knowing the function will be wrapped before
> reading the def, worth the pain of currying the wrapper maker?
If only there were a conceptually simpler way to do this. Actually,
there is. I give you: metadecorators!
First, the simple, non-parameterized case:
from functools import partial
def make_wrapper(wrapper):
return lambda wrapped: partial(wrapper, wrapped)
With that simple function buried in a utility module somewhere, we can do:
@make_wrapper
def simple_decorator(func, *args, **kwargs):
do_stuff()
result = func(*args, **kwargs)
do_more_stuff()
return result
Which I think is certainly easier to understand than the nested
functions approach. Parameterized decorators are not much more
difficult this way. This function:
def make_parameterized_wrapper(wrapper):
return lambda *params: lambda wrapped: partial(wrapper, wrapped, params)
enables us to write:
@make_parameterized_wrapper
def complex_decorator(func, (param1, param2, param3), *args, **kwargs):
do_stuff(param1, param2)
result = func(*args, **kwargs)
do_more_stuff(param2, param3)
return result
And now we have a fancy parameterized decorator that again requires no
thinking about nested functions at all. Sadly, that last bit of
syntax will only work in Python 2; tuple parameter unpacking was
removed in Python 3. It's not a complicated upgrade path, however:
@make_parameterized_wrapper
def complex_decorator(func, params, *args, **kwargs):
(param1, param2, param3) = params
do_stuff(param1, param2)
result = func(*args, **kwargs)
do_more_stuff(param2, param3)
return result
Cheers,
Ian
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2012-09-14 23:39 +0000 |
| Subject | Re: Decorators not worth the effort |
| Message-ID | <5053c030$0$29981$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #29190 |
On Fri, 14 Sep 2012 15:16:47 -0600, Ian Kelly wrote:
> If only there were a conceptually simpler way to do this. Actually,
> there is. I give you: metadecorators!
[code snipped but shown below]
> Which I think is certainly easier to understand than the nested
> functions approach.
Maybe for you, but to me it is a big ball of mud. I have no idea how this
is supposed to work! At a quick glance, I would have sworn that it
*can't* work, since simple_decorator needs to see multiple arguments but
only receives one, the function to be decorated. And yet it does work:
py> from functools import partial
py> def make_wrapper(wrapper):
... return lambda wrapped: partial(wrapper, wrapped)
...
py> @make_wrapper
... def simple_decorator(func, *args, **kwargs):
... print "Entering decorated function"
... result = func(*args, **kwargs)
... print "Exiting decorated function"
... return result
...
py> @simple_decorator
... def my_function(a, b, c):
... """Doc string"""
... return a+b+c
...
py> my_function(1, 2, 3)
Entering decorated function
Exiting decorated function
6
So to me, this is far more magical than nested functions. If I saw this
in t requires me to hunt through your library for the "simple function
buried in a utility module somewhere" (your words), instead of seeing
everything needed in a single decorator factory function. It requires
that I understand how partial works, which in my opinion is quite tricky.
(I never remember how it works or which arguments get curried.)
And the end result is that the decorated function is less debugging-
friendly than I demand: it is an anonymous partial object instead of a
named function, and the doc string is lost. And it is far from clear to
me how to modify your recipe to use functools.wraps in order to keep the
name and docstring, or even whether I *can* use functools.wraps.
I dare say I could answer all those questions with some experimentation
and research. But I don't think that your "metadecorator" using partial
is *inherently* more understandable than the standard decorator approach:
def simple_decorator2(func):
@functools.wraps(func)
def inner(*args, **kwargs):
print "Entering decorated function"
result = func(*args, **kwargs)
print "Exiting decorated function"
return result
return inner
This is no more complex than yours, and it keeps the function name and
docstring.
> Parameterized decorators are not much more
> difficult this way. This function:
[snip code]
> And now we have a fancy parameterized decorator that again requires no
> thinking about nested functions at all.
Again, at the cost of throwing away the function name and docstring.
I realise that a lot of this boils down to personal preference, but I
just don't think that nested functions are necessarily that hard to
grasp, so I prefer to see as much of the decorator logic to be in one
place (a nested decorator function) rather than scattered across two
separate decorators plus partial.
--
Steven
[toc] | [prev] | [next] | [standalone]
| From | 88888 Dihedral <dihedral88888@googlemail.com> |
|---|---|
| Date | 2012-09-15 02:45 -0700 |
| Subject | Re: Decorators not worth the effort |
| Message-ID | <a6de2f24-c9af-4193-8ce3-63743fe424be@googlegroups.com> |
| In reply to | #29195 |
Steven D'Aprano於 2012年9月15日星期六UTC+8上午7時39分28秒寫道:
> On Fri, 14 Sep 2012 15:16:47 -0600, Ian Kelly wrote:
>
>
>
> > If only there were a conceptually simpler way to do this. Actually,
>
> > there is. I give you: metadecorators!
>
> [code snipped but shown below]
>
> > Which I think is certainly easier to understand than the nested
>
> > functions approach.
>
>
>
> Maybe for you, but to me it is a big ball of mud. I have no idea how this
>
> is supposed to work! At a quick glance, I would have sworn that it
>
> *can't* work, since simple_decorator needs to see multiple arguments but
>
> only receives one, the function to be decorated. And yet it does work:
>
>
>
> py> from functools import partial
>
> py> def make_wrapper(wrapper):
>
> ... return lambda wrapped: partial(wrapper, wrapped)
>
> ...
>
> py> @make_wrapper
>
> ... def simple_decorator(func, *args, **kwargs):
>
> ... print "Entering decorated function"
>
> ... result = func(*args, **kwargs)
>
> ... print "Exiting decorated function"
>
> ... return result
>
> ...
>
> py> @simple_decorator
>
> ... def my_function(a, b, c):
>
> ... """Doc string"""
>
> ... return a+b+c
>
> ...
>
> py> my_function(1, 2, 3)
>
> Entering decorated function
>
> Exiting decorated function
>
> 6
>
>
>
> So to me, this is far more magical than nested functions. If I saw this
>
> in t requires me to hunt through your library for the "simple function
>
> buried in a utility module somewhere" (your words), instead of seeing
>
> everything needed in a single decorator factory function. It requires
>
> that I understand how partial works, which in my opinion is quite tricky.
>
> (I never remember how it works or which arguments get curried.)
>
>
>
> And the end result is that the decorated function is less debugging-
>
> friendly than I demand: it is an anonymous partial object instead of a
>
> named function, and the doc string is lost. And it is far from clear to
>
> me how to modify your recipe to use functools.wraps in order to keep the
>
> name and docstring, or even whether I *can* use functools.wraps.
>
>
>
> I dare say I could answer all those questions with some experimentation
>
> and research. But I don't think that your "metadecorator" using partial
>
> is *inherently* more understandable than the standard decorator approach:
>
>
>
> def simple_decorator2(func):
>
> @functools.wraps(func)
>
> def inner(*args, **kwargs):
>
> print "Entering decorated function"
>
> result = func(*args, **kwargs)
>
> print "Exiting decorated function"
>
> return result
>
> return inner
>
>
>
> This is no more complex than yours, and it keeps the function name and
>
> docstring.
>
>
>
>
>
> > Parameterized decorators are not much more
>
> > difficult this way. This function:
>
> [snip code]
>
> > And now we have a fancy parameterized decorator that again requires no
>
> > thinking about nested functions at all.
>
>
>
> Again, at the cost of throwing away the function name and docstring.
>
>
>
> I realise that a lot of this boils down to personal preference, but I
>
> just don't think that nested functions are necessarily that hard to
>
> grasp, so I prefer to see as much of the decorator logic to be in one
>
> place (a nested decorator function) rather than scattered across two
>
> separate decorators plus partial.
>
>
>
>
>
>
>
>
>
> --
>
> Steven
I think the problem is not in the replaced f.__doc__.
def MIGHT_FAIL(f, MSG, *k, **h):
# use MSG to determine whether to invoke f or not
# and do an error catch here
....
def innner(f): .....
......
# get the right info of f here for any trapped error
#return inner, result
return inner
[toc] | [prev] | [next] | [standalone]
| From | Dwight Hutto <dwightdhutto@gmail.com> |
|---|---|
| Date | 2012-09-15 06:04 -0400 |
| Subject | Re: Decorators not worth the effort |
| Message-ID | <mailman.742.1347703468.27098.python-list@python.org> |
| In reply to | #29215 |
On Sat, Sep 15, 2012 at 5:45 AM, 88888 Dihedral <dihedral88888@googlemail.com> wrote: > Steven D'Aprano於 2012年9月15日星期六UTC+8上午7時39分28秒寫道: >> On Fri, 14 Sep 2012 15:16:47 -0600, Ian Kelly wrote: >> >> >> >> > If only there were a conceptually simpler way to do this. Actually, >> >> > there is. I give you: muman than humanetadecorators! >> >> [code snipped but shown below] >> >> > Which I think is certainly easier to understand than the nested >> >> > functions approach. >> >> >> >> Maybe for you, but to me it is a big ball of mud. I have no idea how this >> >> is supposed to work! At a quick glance, I would have sworn that it >> >> *can't* work, since simple_decorator needs to see multiple arguments but >> >> only receives one, the function to be decorated. And yet it does work: >> >> >> >> py> from functools import partial >> >> py> def make_wrapper(wrapper): >> >> ... return lambda wrapped: partial(wrapper, wrapped) >> >> ... >> >> py> @make_wrapper >> >> ... def simple_decorator(func, *args, **kwargs): >> >> ... print "Entering decorated function" >> >> ... result = func(*args, **kwargs) >> >> ... print "Exiting decorated function" >> >> ... return result >> >> ... >> >> py> @simple_decorator >> >> ... def my_function(a, b, c): >> >> ... """Doc string""" >> >> ... return a+b+c >> >> ... >> >> py> my_function(1, 2, 3) >> >> Entering decorated function >> >> Exiting decorated function >> >> 6 >> >> >> >> So to me, this is far more magical than nested functions. If I saw this >> >> in t requires me to hunt through your library for the "simple function >> >> buried in a utility module somewhere" (your words), instead of seeing >> >> everything needed in a single decorator factory function. It requires >> >> that I understand how partial works, which in my opinion is quite tricky. >> >> (I never remember how it works or which arguments get curried.) >> >> >> >> And the end result is that the decorated function is less debugging- >> >> friendly than I demand: it is an anonymous partial object instead of a >> >> named function, and the doc string is lost. And it is far from clear to >> >> me how to modify your recipe to use functools.wraps in order to keep the >> >> name and docstring, or even whether I *can* use functools.wraps. >> >> >> >> I dare say I could answer all those questions with some experimentation >> >> and research. But I don't think that your "metadecorator" using partial >> >> is *inherently* more understandable than the standard decorator approach: >> >> >> >> def simple_decorator2(func): >> >> @functools.wraps(func) >> >> def inner(*args, **kwargs): >> >> print "Entering decorated function" >> >> result = func(*args, **kwargs) >> >> print "Exiting decorated function" >> >> return result >> >> return inner >> >> >> >> This is no more complex than yours, and it keeps the function name and >> >> docstring. >> >> >> >> >> >> > Parameterized decorators are not much more >> >> > difficult this way. This function: >> >> [snip code] >> >> > And now we have a fancy parameterized decorator that again requires no >> >> > thinking about nested functions at all. >> >> >> >> Again, at the cost of throwing away the function name and docstring. >> >> >> >> I realise that a lot of this boils down to personal preference, but I >> >> just don't think that nested functions are necessarily that hard to >> >> grasp, so I prefer to see as much of the decorator logic to be in one >> >> place (a nested decorator function) rather than scattered across two >> >> separate decorators plus partial. Like chi fu, allow decorators to evolve upon themselves. Like simple moves flow through water and allow memorization of activity through evidence of existence. -- Best Regards, David Hutto CEO: http://www.hitwebdevelopment.com
[toc] | [prev] | [next] | [standalone]
| From | 88888 Dihedral <dihedral88888@googlemail.com> |
|---|---|
| Date | 2012-09-15 07:18 -0700 |
| Subject | Re: Decorators not worth the effort |
| Message-ID | <331d26cd-8bb9-4994-9adf-fa2462bcfd6e@googlegroups.com> |
| In reply to | #29216 |
David Hutto於 2012年9月15日星期六UTC+8下午6時04分28秒寫道: > On Sat, Sep 15, 2012 at 5:45 AM, 88888 Dihedral > > <dihedral88888@googlemail.com> wrote: > > > Steven D'Aprano於 2012年9月15日星期六UTC+8上午7時39分28秒寫道: > > >> On Fri, 14 Sep 2012 15:16:47 -0600, Ian Kelly wrote: > > >> > > >> > > >> > > >> > If only there were a conceptually simpler way to do this. Actually, > > >> > > >> > there is. I give you: muman than humanetadecorators! > > >> > > >> [code snipped but shown below] > > >> > > >> > Which I think is certainly easier to understand than the nested > > >> > > >> > functions approach. > > >> > > >> > > >> > > >> Maybe for you, but to me it is a big ball of mud. I have no idea how this > > >> > > >> is supposed to work! At a quick glance, I would have sworn that it > > >> > > >> *can't* work, since simple_decorator needs to see multiple arguments but > > >> > > >> only receives one, the function to be decorated. And yet it does work: > > >> > > >> > > >> > > >> py> from functools import partial > > >> > > >> py> def make_wrapper(wrapper): > > >> > > >> ... return lambda wrapped: partial(wrapper, wrapped) > > >> > > >> ... > > >> > > >> py> @make_wrapper > > >> > > >> ... def simple_decorator(func, *args, **kwargs): > > >> > > >> ... print "Entering decorated function" > > >> > > >> ... result = func(*args, **kwargs) > > >> > > >> ... print "Exiting decorated function" > > >> > > >> ... return result > > >> > > >> ... > > >> > > >> py> @simple_decorator > > >> > > >> ... def my_function(a, b, c): > > >> > > >> ... """Doc string""" > > >> > > >> ... return a+b+c > > >> > > >> ... > > >> > > >> py> my_function(1, 2, 3) > > >> > > >> Entering decorated function > > >> > > >> Exiting decorated function > > >> > > >> 6 > > >> > > >> > > >> > > >> So to me, this is far more magical than nested functions. If I saw this > > >> > > >> in t requires me to hunt through your library for the "simple function > > >> > > >> buried in a utility module somewhere" (your words), instead of seeing > > >> > > >> everything needed in a single decorator factory function. It requires > > >> > > >> that I understand how partial works, which in my opinion is quite tricky. > > >> > > >> (I never remember how it works or which arguments get curried.) > > >> > > >> > > >> > > >> And the end result is that the decorated function is less debugging- > > >> > > >> friendly than I demand: it is an anonymous partial object instead of a > > >> > > >> named function, and the doc string is lost. And it is far from clear to > > >> > > >> me how to modify your recipe to use functools.wraps in order to keep the > > >> > > >> name and docstring, or even whether I *can* use functools.wraps. > > >> > > >> > > >> > > >> I dare say I could answer all those questions with some experimentation > > >> > > >> and research. But I don't think that your "metadecorator" using partial > > >> > > >> is *inherently* more understandable than the standard decorator approach: > > >> > > >> > > >> > > >> def simple_decorator2(func): > > >> > > >> @functools.wraps(func) > > >> > > >> def inner(*args, **kwargs): > > >> > > >> print "Entering decorated function" > > >> > > >> result = func(*args, **kwargs) > > >> > > >> print "Exiting decorated function" > > >> > > >> return result > > >> > > >> return inner > > >> > > >> > > >> > > >> This is no more complex than yours, and it keeps the function name and > > >> > > >> docstring. > > >> > > >> > > >> > > >> > > >> > > >> > Parameterized decorators are not much more > > >> > > >> > difficult this way. This function: > > >> > > >> [snip code] > > >> > > >> > And now we have a fancy parameterized decorator that again requires no > > >> > > >> > thinking about nested functions at all. > > >> > > >> > > >> > > >> Again, at the cost of throwing away the function name and docstring. > > >> > > >> > > >> > > >> I realise that a lot of this boils down to personal preference, but I > > >> > > >> just don't think that nested functions are necessarily that hard to > > >> > > >> grasp, so I prefer to see as much of the decorator logic to be in one > > >> > > >> place (a nested decorator function) rather than scattered across two > > >> > > >> separate decorators plus partial. > > > > Like chi fu, allow decorators to evolve upon themselves. Like simple > > moves flow through water and allow memorization of activity through > > evidence of existence. > > > > > > -- > > Best Regards, The concept of decorators is just a mapping from a function to another function with the same name in python. It should be easy to be grapsed for those studied real analysis and functional analysis.
[toc] | [prev] | [next] | [standalone]
| From | Thomas Rachel <nutznetz-0c1b6768-bfa9-48d5-a470-7603bd3aa915@spamschutz.glglgl.de> |
|---|---|
| Date | 2012-09-18 14:16 +0200 |
| Subject | Re: Decorators not worth the effort |
| Message-ID | <k39omn$qe9$1@r03.glglgl.gl> |
| In reply to | #29229 |
Am 15.09.2012 16:18 schrieb 88888 Dihedral: > The concept of decorators is just a mapping from a function ... or class ... > to another function ... or any other object ... > with the same name in python. Thomas
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.python
csiph-web