Why is this not working ?
u = {}
for me in ['foo', 'bar']:
def callback():
return 'I am %s' % me
u[me] = callback
The output I get is:
>>> u['foo']()
'I am bar'
It seems the callback
is defined once at the latest iteration.
EDIT
As proposed by kawadhiya21, a class approach would work:
class CallbackFactory():
def __init__(self, me):
self.me = me
def __call__(self):
return 'I am %s' % self.me
u = {}
for me in ['foo', 'bar']:
u[me] = CallbackFactory(me)
But it is far more complicated than the former approach.
Accepted Answer "function" as a keyword is only used for defining functions, and cannot be used inside a loop (or inside an "if" or "switch" or other control statement.) The only kinds of functions that can be defined within loops are anonymous functions.
Python call function inside for loop A Python for loop is used to loop through an iterable object (like a list, tuple, set, etc.) and perform the same action for each entry. We can call a function from inside of for loop.
When we log a function call expression the output is the return value of the function. We logged the return value of a self-invoking (it called itself) anonymous function expression. This proves that we can run a function inside a loop.
You should not define a function inside a loop because you'll encounter errors unless you add a check before the function declaration to see if the function already exists. if (menuSelect == 2); --> ; is not required in your case.
All your functions are referencing the same variable me
. When you try and call the function, me
has the value 'bar'
, because that's what it was when the loop ended.
If you want me
to take a different value for each definition of the function, then each function needs its own copy of the variable.
u = {}
for me in ['foo', 'bar']:
def callback(me_copy=me):
return 'I am %s' % me_copy
u[me] = callback
If you wanted, you could shorten that to:
u = {}
for me in ['foo', 'bar']:
u[me] = lambda me_copy=me: 'I am %s'%me_copy
or even
u = { me: (lambda me_copy=me: 'I am %s'%me_copy) for me in ('foo', 'bar') }
First off, in your example, u['foo']
should not return a string at all, but a function handle. :) EDIT: this sentence is no longer relevant.
Second, your function callback
uses me
, from the outer scope. If you change this value (in your case by your loop) in the outer scope, then the function's output also changes.
To fix this, you need to make me
part of the function's own scope, e.g. by doing:
def callback(int_me=me):
return 'I am %s' % int_me
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With