Reputation: 23
I'm trying to wrap my head around the scope of Lambda functions. I noticed that I can create a lambda function in one module A and pass it to a function in another module B, but able to call functions from module A .
Is this bad practice to pass lambda functions around like this, or is there a more preferred (Best Practice) method for handling this?
target.py
class TestLambda():
def __init__(self,name):
self.name = name
def call(self,func):
func(self.name)
source.py
from target import TestLambda
def sayHello(name):
print("Hello {}".format(name))
func = lambda n: sayHello(n)
l = TestLambda("John")
l.call(func)
output
➜ lambda-test python3 source.py
Hello John
Upvotes: 2
Views: 398
Reputation: 531125
The key here is that every function
object keeps a reference to the scope in which the function was defined.
>>> func.__globals__['sayHello']
<function sayHello at 0x1085f2680>
This is what lets func
still call sayHello
even when called from a function with a different global scope. Name lookups are static; they depend only on the lexical (static) context in which the names appear, not the runtime (dynamic) context. There are languages (Lisp, shell, etc) that use dynamic scoping; lexical or static scoping is widely regarded as easier to reason about, though.
Upvotes: 2
Reputation: 5405
I don't think there are any issues with creating and passing lambda functions around, as opposed to using
def func(name):
but I don't see the point in defining a function as a lambda expression if you are going to use it in a different module.
The result is the same, the only difference is that you're not consistent with your function definitions.
The Python docs specifically discourage this:
Always use a def statement instead of an assignment statement that binds a lambda expression directly to an identifier.
Yes:
def f(x): return 2*x
No:
f = lambda x: 2*x
The first form means that the name of the resulting function object is specifically 'f' instead of the generic ''. This is more useful for tracebacks and string representations in general. The use of the assignment statement eliminates the sole benefit a lambda expression can offer over an explicit def statement (i.e. that it can be embedded inside a larger expression)
Upvotes: 0