[ python-Bugs-1390991 ] lambda functions confused when mapped in dictionary object

SourceForge.net noreply at sourceforge.net
Wed Dec 28 19:52:28 CET 2005


Bugs item #1390991, was opened at 2005-12-26 22:00
Message generated for change (Comment added) made by jimjjewett
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1390991&group_id=5470

Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: Python Interpreter Core
Group: Python 2.4
Status: Open
Resolution: None
Priority: 5
Submitted By: Samuel Hsiung (shsiung)
Assigned to: Nobody/Anonymous (nobody)
Summary: lambda functions confused when mapped in dictionary object

Initial Comment:
***Background***
Lambda functions wrapped around different module
functions overwrite each other when mapped one at a
time in a dictionary object.

Python Version: 2.4.2

***Duplication Instructions***

1. Setup

===module foo.py===
def callme(x):
    print "foo called!"
    print x

===module bar.py===
def callme(x):
    print "bar called!"
    print x

===module call.py===
import foo, bar

api = {}
modules = (foo, bar)

for module in modules:
    api[module] = lambda x: module.callme(x)
    print '%s mapped to %s' % (module, api[module])

api[foo]('above line should be foo')
api[bar]('above line should be bar')

print "foo lambda: %s" % api[foo]
print "bar lambda: %s" % api[bar]


2. Execution
=> python call.py

<module 'foo' from '/home/shsiung/playground/foo.pyc'>
mapped to <function <lambda> at 0xb7f7abc4>
<module 'bar' from '/home/shsiung/playground/bar.pyc'>
mapped to <function <lambda> at 0xb7f7abfc>
bar called!
above line should be foo
bar called!
above line should be bar
foo lambda: <function <lambda> at 0xb7f7abc4>
bar lambda: <function <lambda> at 0xb7f7abfc>

3. Expected behaviour
foo should have been called, followed by bar; instead
bar was called twice.

----------------------------------------------------------------------

Comment By: Jim Jewett (jimjjewett)
Date: 2005-12-28 13:52

Message:
Logged In: YES 
user_id=764593

Not a bug, just part of the ugliness of lambda and scopes, 
masked by a quirk of for loops.

'module' is not a parameter of the lambda, so it is looked 
up in the enclosing scope each time the lambda is called.  

for loops leave their index (in this case, 'module') set at 
the final value, so that value is found in the globals, and 
used by each of the lambdas.

To get what you were expecting, try

api[module]=lambda x,module=module:module.callme(x)

This binds the name 'module' (for that lambda) to whatever 
its current value is, at least as a default.




----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1390991&group_id=5470


More information about the Python-bugs-list mailing list