Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Useful decorator

Reply
Thread Tools

Useful decorator

 
 
Paul Rubin
Guest
Posts: n/a
 
      04-14-2007
In the course of writing a bunch of generator-oriented code I kept
wanting to temporarily truncate the output of generators for debugging,
i.e. I might have a function like

def generate_bazillion_items():
for line in bazillion_line_file:
yield itemify(line)

where I wanted to test the program on just the first 20 lines of the
file. After a number of rounds of editing the program to wrap an
xrange(20) loop I went to using islice(bazillion_line_file, 20), but
even more handy was to write this decorator:

def truncate(n):
from itertools import islice
def trunc(gen): # truncate generator to n items
return lambda *a,**kw: islice(gen(*a,**kw), n)
return trunc

Then to chop bazillion_items to 20 items, I just write:

@truncate(20)
def generate_bazillion_items():
for line in bazillion_line_file:
yield itemify(line)

When I want to run the whole file, I comment out the @truncate line,
and if I want to debug again, I just uncomment it.
 
Reply With Quote
 
 
 
 
James Stroud
Guest
Posts: n/a
 
      04-14-2007
Paul Rubin wrote:
> In the course of writing a bunch of generator-oriented code I kept
> wanting to temporarily truncate the output of generators for debugging,
> i.e. I might have a function like
>
> def generate_bazillion_items():
> for line in bazillion_line_file:
> yield itemify(line)
>
> where I wanted to test the program on just the first 20 lines of the
> file. After a number of rounds of editing the program to wrap an
> xrange(20) loop I went to using islice(bazillion_line_file, 20), but
> even more handy was to write this decorator:
>
> def truncate(n):
> from itertools import islice
> def trunc(gen): # truncate generator to n items
> return lambda *a,**kw: islice(gen(*a,**kw), n)
> return trunc
>
> Then to chop bazillion_items to 20 items, I just write:
>
> @truncate(20)
> def generate_bazillion_items():
> for line in bazillion_line_file:
> yield itemify(line)
>
> When I want to run the whole file, I comment out the @truncate line,
> and if I want to debug again, I just uncomment it.


Thes may be overkill, but how about allowing None as a parameter to
truncate, to allow for programmatic truncation?

# top of module
if DEBUG:
FILETRUNC = 20
else:
FILETRUNC = None

# imported, etc.
def truncate(n):
if n is None:
return lambda gen: gen
from itertools import islice
def trunc(gen): # truncate generator to n items
return lambda *a,**kw: islice(gen(*a,**kw), n)
return trunc

# in the body somewhere
@truncate(FILETRUNC)
def generate_bazillion_items():
# etc.

James
 
Reply With Quote
 
 
 
 
Paul McGuire
Guest
Posts: n/a
 
      04-14-2007
On Apr 14, 5:03 pm, Paul Rubin <http://(E-Mail Removed)> wrote:
> In the course of writing a bunch of generator-oriented code I kept
> wanting to temporarily truncate the output of generators for debugging,
> i.e. I might have a function like
>
> def generate_bazillion_items():
> for line in bazillion_line_file:
> yield itemify(line)
>
> where I wanted to test the program on just the first 20 lines of the
> file. After a number of rounds of editing the program to wrap an
> xrange(20) loop I went to using islice(bazillion_line_file, 20), but
> even more handy was to write this decorator:
>
> def truncate(n):
> from itertools import islice
> def trunc(gen): # truncate generator to n items
> return lambda *a,**kw: islice(gen(*a,**kw), n)
> return trunc
>
> Then to chop bazillion_items to 20 items, I just write:
>
> @truncate(20)
> def generate_bazillion_items():
> for line in bazillion_line_file:
> yield itemify(line)
>
> When I want to run the whole file, I comment out the @truncate line,
> and if I want to debug again, I just uncomment it.


You should add this to the Python Wiki at http://wiki.python.org/moin/PythonDecoratorLibrary

-- Paul

 
Reply With Quote
 
Steven D'Aprano
Guest
Posts: n/a
 
      04-15-2007
On Sat, 14 Apr 2007 15:03:00 -0700, Paul Rubin wrote:

> Then to chop bazillion_items to 20 items, I just write:
>
> @truncate(20)
> def generate_bazillion_items():
> for line in bazillion_line_file:
> yield itemify(line)
>
> When I want to run the whole file, I comment out the @truncate line,
> and if I want to debug again, I just uncomment it.



By All-Father Wodan's one good eye! Why not do something like this?

if __debug__:
generate_bazillion_items = truncate(20)(generate_bazillion_items)

Now you don't have to comment/uncomment dozens of lines all over your
application, but only set a single global.



--
Steven.

 
Reply With Quote
 
Paul Rubin
Guest
Posts: n/a
 
      04-15-2007
Steven D'Aprano <(E-Mail Removed)> writes:
> if __debug__:
> generate_bazillion_items = truncate(20)(generate_bazillion_items)
>
> Now you don't have to comment/uncomment dozens of lines all over your
> application, but only set a single global.


The cool thing about organizing the program as a generator pipeline is
you only have to comment or uncomment one line .
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
useful setting in device manager (may be useful to know!) jameshanley39@yahoo.co.uk Computer Information 2 07-07-2008 04:28 PM
Why doesnt __getattr__ with decorator dont call __get_method in decorator glomde Python 5 03-29-2007 02:48 PM
layout decorator framework that fits well w/ spring William Z. Java 0 03-22-2006 11:19 PM
explanations about the Decorator design pattern Jean Lutrin Java 8 11-18-2004 05:40 PM
tweaking @decorator syntax Sandy Norton Python 14 08-06-2004 08:09 PM



Advertisments