基础篇_010_函数_作用域
"作用域"是紧跟着嵌套函数("基础篇_010_函数_全局变量与局部变量")来讲的,在"全局变量与局部变量"中我们依靠的就是函数的嵌套,这也就牵扯出了一个问题——变量的作用域(这仅仅是同名变量的时候才有此类问题),即这个变量名到底是代指的哪一个值?
----前奏(函数名是个什么东西) ===》
在问题的开始,必须让大家真正认识到函数名是个什么东西。函数名:整个函数的代称,存储的是函数的地址,加上()便可调用函数 ↓
# 1. 函数名是函数的地址
def foo():
pass
print(foo) # 输出函数名:<function foo at 0x000002B1B71A86A8>
print(foo()) # 输出函数的返回值:None
# 2. 函数的返回值为函数名,尝试调用返回值
def foo1():
print("from foo1()")
return foo2
def foo2():
print("from foo2()")
return
result = foo1() # 只是调用foo1()函数,输出 from foo1()
# foo1()的返回值为 foo2,而foo2是foo2()函数的地址 ===》result就是foo2()函数的地址
# 得到了函数的地址,那么加上()便可以运行函数
result() # 执行foo2()函数,输出 from foo2()
----问题的引入(思考一下为什么) ===》
# 1. 当内部函数中已经定义了一个同名的变量
name = "simba"
def foo():
name = "wang"
def bar():
name = "wupeiqi"
print(name)
return bar
foo()() # 输出:wupeiqi
这个很好理解,因为在自己家(bar()函数内部就已经定义了一个name),直接拿来用就行了,不用去外面找。
那我们再来看下一段代码(错误思考方式:仅仅考虑到函数在编译时是以字符串的方式存在内存中的) ===》
# 2. 当内部函数中没有定义同名变量
name = "simba"
def foo():
name = "wang"
def bar():
print(name)
return bar
foo()() # 输出:wang
卧槽,bar()函数不是在全局调用的嘛,怎么不是全局变量"simba",而是局部变量"wang"?
----问题的剖析 ===》
虽然函数在编译时是以字符串的方式存在内存中的,但是于此同时Python还会将函数的嵌套格局(作用域关系)记录下来,由于这是在定义函数时就形成了的,所以无论函数的调用在哪,函数都将按照定义时的格局(作用域关系)来运行,故而上面的例子将会输出"wang"。
----加大力度 ===》
1 # 加大力度
2 name = "simba"
3 def foo_out():
4 name = "from foo_out()"
5 def foo_middle():
6 name = "from foo_middle()"
7 def foo_in():
8 print(name)
9 # end foo_in()
10 return foo_in
11 # end foo_middle()
12 return foo_middle
13 # end foo_out()
14
15 foo_out()()()
16 # 输出:from foo_middle()
step1(第02行): name = "simba"
step2(第15行): 执行foo_out(),后面两个()先不管
step3(第04行): 创建foo_out()中的局部变量name = "from foo_out()"
step4(第12行): 结束foo_out()函数,返回foo_middle()函数的地址
step5(第15行): 执行(foo_out())(),其中foo_out()的结果就是foo_middle()函数的地址,即执行foo_middle()
step6(第06行): 创建foo_middle()中的局部变量name = "from foo_middle()"
step7(第10行): 结束foo_middle()函数,返回foo_in()函数的地址
step8(第15行): 执行((foo_out())())(),其中(foo_out())()的结果就是foo_in()函数的地址,即执行foo_in()
step9(第08行): 打印name,由于在定义函数时就已经创建出了作用域关系,所以此时的name为"from foo_middle()"

浙公网安备 33010602011771号