Useful decorator

Discussion in 'Python' started by Paul Rubin, Apr 14, 2007.

  1. Paul Rubin

    Paul Rubin Guest

    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.
    Paul Rubin, Apr 14, 2007
    #1
    1. Advertising

  2. Paul Rubin

    James Stroud Guest

    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
    James Stroud, Apr 14, 2007
    #2
    1. Advertising

  3. Paul Rubin

    Paul McGuire Guest

    On Apr 14, 5:03 pm, Paul Rubin <http://> 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
    Paul McGuire, Apr 15, 2007
    #3
  4. 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.
    Steven D'Aprano, Apr 15, 2007
    #4
  5. Paul Rubin

    Paul Rubin Guest

    Steven D'Aprano <> 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 ;).
    Paul Rubin, Apr 15, 2007
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. ben cohen
    Replies:
    0
    Views:
    1,071
    ben cohen
    Aug 20, 2003
  2. Andreas Klemt
    Replies:
    1
    Views:
    399
    Cowboy \(Gregory A. Beamer\)
    Jan 14, 2004
  3. Brock Allen
    Replies:
    4
    Views:
    2,071
    =?Utf-8?B?dHhnaGlhNTg=?=
    Apr 17, 2005
  4. =?Utf-8?B?Sm9obg==?=

    if(blah) alert box else somethinge useful

    =?Utf-8?B?Sm9obg==?=, Jun 9, 2005, in forum: ASP .Net
    Replies:
    3
    Views:
    2,344
    =?Utf-8?B?Sm9obg==?=
    Jun 9, 2005
  5. glomde
    Replies:
    5
    Views:
    514
    glomde
    Mar 29, 2007
Loading...

Share This Page