problem using lambdas for deferred callbacks

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • edd@nunswithguns.net

    #1

    problem using lambdas for deferred callbacks

    I tried searching for an answer to this in the google groups archives
    but I failed to come up with anything. So I hope no one minds me asking
    this, though I'm sure it's been asked a million times before.

    I was hoping that the following code would print "Hello, world!", one
    character per line. But instead it prints an exclamation mark for each
    character of the string. I'm sure it's no coincidence that the last
    value of c is '!', but beyond that I don't understand what's happening.

    # --- begin code ---
    def callback(arg):
    print arg

    funcs = []
    for c in 'Hello, world!':
    funcs.append(la mbda: callback(c))

    for f in funcs:
    f()
    # --- end code ---

    What I'm trying to do is create a 0-args callback by binding an
    argument to a 1-arg function. But failing, miserably :)

    I'm using Python 2.3.5 as installed by default on Mac OS X 10.4 if it
    matters.

    Thanks,

    Edd

  • Marc 'BlackJack' Rintsch

    #2
    Re: problem using lambdas for deferred callbacks

    In <1165764662.462 927.147010@79g2 000cws.googlegr oups.com>, edd wrote:
    I was hoping that the following code would print "Hello, world!", one
    character per line. But instead it prints an exclamation mark for each
    character of the string. I'm sure it's no coincidence that the last
    value of c is '!', but beyond that I don't understand what's happening.
    If you call the lambda function the name `c` is looked up in the
    "environmen t". It's not local to the function.
    # --- begin code ---
    def callback(arg):
    print arg
    >
    funcs = []
    for c in 'Hello, world!':
    funcs.append(la mbda: callback(c))
    Change this line to:

    funcs.append(la mbda x=c: callback(x))

    Now the `c` is bound to the default argument `x` at definition time.

    Ciao,
    Marc 'BlackJack' Rintsch

    Comment

    • Fredrik Lundh

      #3
      Re: problem using lambdas for deferred callbacks

      edd@nunswithgun s.net wrote:
      I was hoping that the following code would print "Hello, world!", one
      character per line. But instead it prints an exclamation mark for each
      character of the string. I'm sure it's no coincidence that the last
      value of c is '!', but beyond that I don't understand what's happening.
      >
      # --- begin code ---
      def callback(arg):
      print arg
      >
      funcs = []
      for c in 'Hello, world!':
      funcs.append(la mbda: callback(c))
      the "lambda" introduces a new function scope, and since the "c" variable
      isn't defined in there, it's bound to the variable with the same name
      from the outer scope. the problem here is that it's bound to the
      *variable*, not the object, so *all* callbacks will use the same value.

      there are several ways to bind to an object value instead; the easiest
      in this case is to use a default argument value:

      for c in 'Hello, world!':
      funcs.append(la mbda c=c: callback(c))

      this turns the inner "c" variable to an argument that defaults to the
      value of the outer "c" at the time the lambda was created.

      </F>

      Comment

      • edd@nunswithguns.net

        #4
        Re: problem using lambdas for deferred callbacks

        Many thanks to you both!

        Edd

        Comment

        Working...