这是对有关 functools.partial 必要性的问题的旧答案的一种后续:虽然该答案非常清楚地解释了这种现象及其基本原因,但我仍然有一些不清楚的地方。
回顾一下,下面的 Python 代码
myfuns = [lambda arg: str(arg) + str(clo) for clo in range(4)]
try :
clo
except NameError :
print("there is no clo")
for arg in range(4) :
print(myfuns[arg](arg), end=", ")
给出03, 13, 23, 33,
,而类似的 OCaml 代码
let myfuns = Array.map (fun clo -> fun arg -> (string_of_int arg) ^ (string_of_int clo)) [|0;1;2;3|];;
(* there is obviously no clo variable here *)
for arg = 0 to 3 do
print_string (myfuns.(arg) arg); print_string ", "
done;;
给00, 11, 22, 33,
.
我知道这与应用于lambda arg: str(arg) + str(clo)
其对应的闭包的不同概念有关fun arg -> (string_of_int arg) ^ (string_of_int clo)
。
在 OCaml 中,闭包在创建闭包时将标识符映射到外部范围内clo
的变量值。clo
在 Python 中,闭包以某种方式包含变量clo
本身,这解释了它受到for
生成器引起的增量的影响。
这个对吗 ?
这是怎么做的?正如我的/构造所证明的那样,该clo
变量在全局范围内不存在。一般来说,我会假设生成器的变量是本地的,因此无法生存。那么,再次,在哪里?这个答案提供了一些见解,但我仍然不完全理解它是如何在生成期间设法引用变量本身的。try
except
clo
__closure__
clo
此外,除了这种奇怪的行为(对于习惯于静态绑定语言的人),还有其他需要注意的警告吗?