python - Python lambda 捕获外部变量
问题描述
考虑以下示例:
test = 123
f = lambda x,test=test: print(x, test)
del test
f('hello')
印刷
hello 123
通过捕获 lambda 定义中的变量,似乎保留了原始变量。
当您还可以使用一个简单的对象来存储相同的数据时,是否可以使用lambda?
class Test:
def __init__(self, some_data):
self.some_data = some_data
def f(self, x):
print(x, self.some_data)
t = Test('123')
t.f('hello')
解决方案
通过捕获 lambda 定义中的变量,似乎保留了原始变量。
因为您将其设置为test
lambda 参数的默认值,并且 Python 仅在创建函数时评估参数默认值一次。lambda
FWIW,这与关键字的使用无关-lambda
只是语法糖,你会得到与“成熟”功能完全相同的结果,即:
test = 123
def f(x, test=test):
print(x, test)
test = 456
f('hello')
当您还可以使用一个简单的对象来存储相同的数据时,是否可以使用 lambda?
橘子和苹果,真的。函数并不是用来“存储”任何东西,而是用来执行一些计算。它可以通过参数默认值或通过闭包捕获一些值,虽然对于某些用例非常有用,但并不意味着可以替代适当的对象或集合。所以答案是:取决于你想用这些值和你的功能做什么。
注意:从技术上讲,您在这里所做的是(几乎)所谓的“部分应用程序”(您只需要重命名Test.f
并在第二个示例中Test.__call__
使用t("hello")
))。函数的部分应用是一种机制,通过该机制,当使用 N - x (x < N) 参数调用具有 N 个参数的函数时,返回一个具有 Nx 参数的函数,当使用缺少的参数调用该函数时,将返回原始函数,即:
def foo(a, b=None):
if b is None:
return lambda b, a=a: foo(b, a)
return a + b
# here, `f` is a partial application of function `foo` to `1`
f = foo(1)
print(f)
f(2)
在这种情况下,我们使用闭包来捕获a
,在函数式编程传统中——“部分应用程序”也主要是 FWIW 的函数式编程概念。现在,虽然它确实支持一些 FP 特性和习语,但 Python 首先是一种 OO 语言,并且由于闭包是对象的 FP 等价物(闭包是一种将状态和行为封装在一起的方法),实现部分应用程序也很有意义作为适当的类,可以使用“ad hoc”专用对象(您的Test
类还有Method
对象),或者使用更通用的“部分”类 - 它已经存在于标准库中functools.partial
推荐阅读
- react-native - 如何浏览页面?反应原生
- c++ - Visual Studio 2017 错误 - 找不到特定文件
- node.js - 将 NodeJS Express API 部署到 AWS
- multithreading - Requests-html 中的线程/异步
- angular-components - 单击Angular-6中的其他下拉输入字段时下拉列表未关闭
- sbt-plugin - 如何在所有项目中收集 SettingKey 的所有值以用于 sbt 插件?
- linux - perl Term::ANSIColor 在 Raspberry Pi 控制台上不起作用
- html - 对齐父 div 中包含的左右元素
- java - 链表算法
- kivy - Qpython - Kivy 应用程序失败“没有名为 kivy 的模块”