Closures / Blocks in Python

Discussion in 'Python' started by treble54, Jul 24, 2007.

  1. treble54

    treble54 Guest

    Does anyone know a way to use closures or blocks in python like those
    used in Ruby? Particularly those used in the { } braces.
    treble54, Jul 24, 2007
    #1
    1. Advertising

  2. On Tue, 2007-07-24 at 14:58 +0000, treble54 wrote:
    > Does anyone know a way to use closures or blocks in python like those
    > used in Ruby? Particularly those used in the { } braces.


    Please describe the problem you're trying to solve. Even if Python had a
    direct equivalent of "Ruby closures or blocks", which I don't think it
    does, it may not be the best solution to your problem.

    --
    Carsten Haese
    http://informixdb.sourceforge.net
    Carsten Haese, Jul 24, 2007
    #2
    1. Advertising

  3. treble54

    Neil Cerutti Guest

    On 2007-07-24, treble54 <> wrote:
    > Does anyone know a way to use closures or blocks in python like
    > those used in Ruby? Particularly those used in the { } braces.


    Python's nameless functions are week. So it supports iterators
    and generators using protocols, comprehensions and a few simple
    statements, rather than promoting the use of nameless functions.

    Ruby's

    some_list.each do |item|
    puts item
    end

    if I understood it correctly, In Python would be:

    for item in some_list:
    print item

    That works for any object that supports the iterator protocol.

    --
    Neil Cerutti
    Neil Cerutti, Jul 24, 2007
    #3
  4. treble54

    Jason Guest

    On Jul 24, 8:58 am, treble54 <> wrote:
    > Does anyone know a way to use closures or blocks in python like those
    > used in Ruby? Particularly those used in the { } braces.


    Python isn't Ruby. Python has a lambda function for creating
    anonymous functions, but many of the common use cases expired with the
    introduction of iterators and comprehensions. Python's functions are
    first class objects, and can be passed around, bound to names, and
    used like any other object. (I don't know whether Ruby's functions
    are first class objects.) Python's function objects are callable, but
    so are classes (calling them creates a class instance) and some
    instances (those that define the __call__ special method).

    If you can't find a way of doing what you want with iterators,
    comprehensions, or lambda, consider writing a little function. Heck,
    you can even nest functions in Python or pass a function as a
    parameter.

    For example, removing all names that start with a 'J' from a list of
    names:
    newListOfNames = [ name for name in nameList if not
    name.startswith('J') ] # List comprehension
    newListOfNames = filter(lambda name: not name.startswith('J'),
    nameList) # Filter with lambda

    # Explicit for-loop
    newListOfNames = []
    for name in nameList:
    if not name.startswith('J'): newListOfNames.append(name)


    Take a look at "http://ivan.truemesh.com/archives/000392.html" for a
    comparison between some simple Ruby code and Python. Hope this helps.

    --Jason
    Jason, Jul 24, 2007
    #4
  5. treble54 a écrit :
    > Does anyone know a way to use closures or blocks in python like those
    > used in Ruby? Particularly those used in the { } braces.
    >

    Instead of looking for what you think is the solution, you'd be better
    explaining your concrete problem.
    Bruno Desthuilliers, Jul 24, 2007
    #5
  6. In article <>,
    Jason <> wrote:
    .
    [good detail]
    .
    .
    >If you can't find a way of doing what you want with iterators,
    >comprehensions, or lambda, consider writing a little function. Heck,

    .
    .
    .
    "[C]onsider writing a little function", indeed; that's
    a crucial summary. From a Ruby or Lisp perspective,
    this proliferation of named functions is clumsy and
    unsightly; Pythoneers see small def-s as opportunities
    to clarify. I've come to suspect both sides are right.
    The marvelous thing is that, taken as a whole, each of
    Python, Ruby, ... *works*, and admits a strong, effec-
    tive style. Moreover, they share enough conceptually
    that it's not hard for speakers of one to understand
    the others. As has already been proposed in this
    thread, though, good Ruby and good Python will always
    look different.
    Cameron Laird, Jul 25, 2007
    #6
  7. treble54

    Jeff Guest

    You can create a lexical closure using a Python generator function,
    which allows iteration using a block of code while maintaining
    internal state. A generator is a regular function which uses yield
    (like Ruby) to define the point at which the function should return an
    expression to the calling code. For example:

    # Generic counter
    def counter(min=None, max):
    if not min:
    min = 0
    for i in xrange(min, max):
    yield i
    i = i + 1

    When called, this function will yield the value of i and remember its
    state. The next time it's called, it will increment i, then continue
    on another iteration of the loop, yielding the new value of i.

    For example:

    my_counter = counter(0, 10)
    my_counter() # <-- 0
    my_counter() # <-- 1
    for i in my_counter():
    print i
    # Prints 2-10 (the remaining numbers in xrange(min, max))
    Jeff, Jul 25, 2007
    #7
  8. Jeff wrote:
    > # Generic counter
    > def counter(min=None, max):
    > if not min:
    > min = 0
    > for i in xrange(min, max):
    > yield i
    > i = i + 1
    >

    Just for the record:
    >>> # Generic counter

    .... def counter(min=None, max):
    .... if not min:
    .... min = 0
    .... for i in xrange(min, max):
    .... yield i
    .... i = i + 1
    ....
    File "<stdin>", line 2
    SyntaxError: non-default argument follows default argument


    You'd have to add a little more parameter-checking for this to work like
    you intend.
    /W
    Wildemar Wildenburger, Jul 25, 2007
    #8
  9. treble54

    Jeff Guest

    True, and I should have known better than to not have thoroughly
    tested code I post to Usenet :). That being said, it was intended as
    a fast example of how a generator operates for someone coming from
    Ruby.
    Jeff, Jul 25, 2007
    #9
  10. treble54

    Klaas Guest

    On Jul 24, 7:58 am, treble54 <> wrote:
    > Does anyone know a way to use closures or blocks in python like those
    > used in Ruby? Particularly those used in the { } braces.


    Inner functions allow you to define closures and (named) blocks
    anywhere). Anonymous blocks must consist of a single expression.

    -Mike
    Klaas, Jul 25, 2007
    #10
  11. En Wed, 25 Jul 2007 11:45:00 -0300, Jeff <> escribió:

    > You can create a lexical closure using a Python generator function,
    > which allows iteration using a block of code while maintaining
    > internal state. A generator is a regular function which uses yield
    > (like Ruby) to define the point at which the function should return an
    > expression to the calling code. For example:
    >
    > # Generic counter
    > def counter(min=None, max):
    > if not min:
    > min = 0
    > for i in xrange(min, max):
    > yield i
    > i = i + 1
    >
    > When called, this function will yield the value of i and remember its
    > state. The next time it's called, it will increment i, then continue
    > on another iteration of the loop, yielding the new value of i.
    >
    > For example:
    >
    > my_counter = counter(0, 10)
    > my_counter() # <-- 0
    > my_counter() # <-- 1
    > for i in my_counter():
    > print i
    > # Prints 2-10 (the remaining numbers in xrange(min, max))


    Uhmm, I think this won't win the Best Python Code Of The Week Award :)
    Apart from the already noted syntax error in the function definition, the
    `i = i + 1` is useless because `i` gets reassigned right on the next loop.
    And you don't "call" a generator, you have to iterate over it;
    my_counter() will raise an error. This would be the right way:

    my_counter = counter(0, 10)
    my_counter.next() <-- 0
    my_counter.next() <-- 1
    for value in my_counter:
    print value <-- 2 to 9

    --
    Gabriel Genellina
    Gabriel Genellina, Jul 26, 2007
    #11
    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. Arjen
    Replies:
    3
    Views:
    418
    Scott Allen
    Feb 27, 2005
  2. Kasper B. Graversen

    Closures in python

    Kasper B. Graversen, Sep 18, 2003, in forum: Python
    Replies:
    11
    Views:
    677
    David Eppstein
    Sep 21, 2003
  3. Alex McHale

    Blocks and Closures

    Alex McHale, Jun 1, 2004, in forum: Ruby
    Replies:
    7
    Views:
    85
    Joel VanderWerf
    Jun 2, 2004
  4. matt
    Replies:
    1
    Views:
    233
    George Ogata
    Aug 6, 2004
  5. Steven Taylor
    Replies:
    9
    Views:
    231
    Brian Candler
    Apr 27, 2009
Loading...

Share This Page