在上一篇 Python札记20_递归、传递 文章中重点介绍了递归函数中的斐波那契数列的实现,以及函数当做参数进行传递的知识。函数不仅可以当做对象进行传递,还能在函数里面嵌套另一个函数,称之为函数嵌套
。
通过一个例子来理解嵌套函数的使用:
def foo():
def bar():
print("bar() is running")
print("foo() is running")
foo()
结果
foo() is running #bar函数没有运行,因为它没有被调用
如果想让bar()
执行,进行如下操作:
def foo():
def bar():
print("bar() is running")
bar()
print("foo() is running")
foo()
结果:
bar() is running
foo() is running
image.png
函数bar
是在foo
里面进行定义的,它的作用域只在foo
函数范围之内;如果把bar
函数放在外面执行,调用则会报错:
同时bar
的变量也会受到far
函数的约束:
def foo():
a = 1
def bar():
a = a + 1
print("bar()a=", a)
bar()
print("foo()a=", a)
foo()`
运行报错:
- 在
bar
里面使用了变量a
,Python
解释器会认为a
变量是建立在bar
内部的局部变量nonlocal
,而不是引用的外部对象。
UnboundLocalError Traceback (most recent call last)
<ipython-input-23-0c4c07078810> in <module>
6 bar()
7 print("foo()a=", a)
----> 8 foo()
<ipython-input-23-0c4c07078810> in foo()
4 a = a + 1
5 print("bar()a=", a)
----> 6 bar()
7 print("foo()a=", a)
8 foo()
<ipython-input-23-0c4c07078810> in bar()
2 a = 1
3 def bar():
----> 4 a = a + 1
5 print("bar()a=", a)
6 bar()
UnboundLocalError: local variable 'a' referenced before assignment
使用nonlocal
关键字来解决:
def foo():
a = 1
def bar():
nonlocal a
a = a + 1
print("bar()a=", a)
bar()
print("foo()a=", a)
foo()
image.png
注意a值的变化
- 定义变量
a=1
- 执行
bar
函数,a
变成2 - 最后执行第二个
print
函数,a=2
,程序是按照自顶向下的顺序执行整个代码块。
def foo():
a = 1
def bar():
a = 1
a = a + 1
print("bar()a=", a)
bar()
print("foo()a=", a)
foo()
image.png
def foo():
a = 1
def bar(a):
a = a + 1
print("bar()a=", a)
bar(a)
print("foo()a=", a)
foo()
image.png
嵌套函数的实际使用:计算重力的函数
def weight(g):
def cal_mg(m):
return m * g
return cal_mg
w = weight(9.8)
mg = w(5)
mg
理解:
w = weight(10):weight
函数中传递了参数10w
引用的是一个函数对象(cal_mg);cal_mg
是一个动态函数
w(10)
向所引用的函数对象cal_mg
传递了参数5- 计算并返回
mg
的值