按照python的LEGB(Local,Enclosing,Global,Built-in)规则,当调用inner()时,x实际上是在foo的scope中找到的。inner之所能够访问foo中的x,是因为inner is inside the text of foo,这正是lexical的含义。
Bash是Dynamic Scoping的
x=1
function g () { echo $x ; x=2 ; }
function f () { local x=3 ; g ; }
f #f中的g执行时打印出的x是3而不是1
echo $x #这时打印出的x是1
你以为Python是
let foo () =
let x = 1 in
let inner () = x + 1 in
let x = 3 in
print (inner ())
python的闭包里的自由变量是按引用传递的,而不是按值传递,所以会有这个结果。 这和scoping没有关系。 C++的lambda就可以选择capture by copy或者capture by reference.
根据之前阅读Python源码的经验(如果记错请指正),在题主的例子里面,这个inner是一个闭包。闭包在Python里面的实现方式是保存一个通往外部namespace的指针(可以理解成一个dictionary)。
楼主可以参看这个例子
def foo():
def inner():
return x + 1
x = 1
print inner() # output 2
x = 2
print inner() # output 3
这段代码是lexical scoping,静态作用域是指我们可以根据代码文本的位置,确定变量的存在区域。 按照python的LEGB(Local,Enclosing,Global,Built-in)规则,当调用inner()时,x实际上是在foo的scope中找到的。inner之所能够访问foo中的x,是因为inner is inside the text of foo,这正是lexical的含义。
Bash是Dynamic Scoping的
x=1 function g () { echo $x ; x=2 ; } function f () { local x=3 ; g ; } f #f中的g执行时打印出的x是3而不是1 echo $x #这时打印出的x是1