Professional Documents
Culture Documents
def fun():
x=3 def fun(x):
return x + x x=6
return x + x def fun():
x=5 return x + x
print(fun()) x=5
print(x) print(fun(x)) x=5
print(x)
print(fun())
print(x)
本章节目标
掌握变量的作用域应用
掌握匿名函数应用方法
了解递归函数应用方法
1 变量的作用域
2 匿名函数
3 递归函数
课程目录 4 闭包
Course catalogue
变量的作用域是指变量的作用范围,即定义一个变量
后,在哪些地方可以使用这个变量。按照作用域的不同,
Python中的变量可分为局部变量和全局变量。
在一个函数中定义的变量就是局部变量(包括形参),其作用域
是从定义局部变量的位置至函数结束位置
b = b + 10 b = 10
print(b) print(b)
no binding for nonlocal ‘b’ found
do_global() do_local()
print(b) print(b)
add_b() add_b()
1 变量的作用域
2 匿名函数
3 递归函数
课程目录 4 闭包
Course catalogue
lambda表达式用来声明匿名函数,即没有函数名称的
临时使用的函数,尤其适合需要一个函数作为另一个函数参数
的场合。
➢函数名是可选项。没有函数名,表示是一个匿名函数。
➢可以接收多个参数,但只能包含一个表达式。
➢lambda表达式相当于只有一条return语句的函数,表达式
的值作为函数的返回值。
• 函数与lambda表达式
def my_add(x, y):
return x + y
my_add = lambda x, y : x + y
• 调用lambda表达式
my_add(3,5) # 结果:8
my_add('hello ', 'world') # 结果:'hello world'
def s(x):
if x==1:
return "yes" s=lambda x:"yes" if x==1 else "no"
else: print(s(0))
return "no" print(s(1))
print(s(0))
print(s(1))
lambda表达式尤其适合需要一个函数作为另一个函数参
数的场合。
lambda函数+map函数
Python中的map()函数是一个将给定的序列的值依次在所定义的函
数关系中迭代。
my_list = [2,3,4,5,6,7,8]
new_list = list(map(lambda x:(x %2==0),my_list ))
print(new_list))
my_list = [2,3,4,5,6,7,8]
new_list = list(filter( lambda x:(x %2==0),my_list))
print(new_list)
输出结果为:[2, 4, 6, 8]
x=10
a=lambda y:x+y lambda表达式中的x是
x=20 一个自由变量,在运行时
b=lambda y:x-y 绑定值,而不是在定义时
就绑定;
print(a(20),b(10))
输出结果:40 10
如果让某个匿名函数在定义时就捕获到值,可以给
参数设置默认值;
x=10
a=lambda y,x=x:x+y
输出结果:30 10
x=20
b=lambda y,x=x:x-y
print(a(20),b(10))
1 变量的作用域
2 匿名函数
3 递归函数
课程目录 4 闭包
Course catalogue
➢ 函数的递归调用是函数调用的一种特殊情况。函数反复的
自己调用自己,直到当某个条件满足的时候就不再调用
了,然后再一层一层地返回直到该函数第一次调用的位置。
➢ 把一个大型复杂的问题层层转化为一个与原问题相似的规模
较小的问题来求解。
递归函数的求解
➢分解之后待解决的子问题与原问题有着相同的特性和解法;
➢在问题规模上与原问题相比有所减小;
➢每调用一次自身,相当于复制一份该函数,只不过参数有
变化,参数的变化,就是重要的结束条件;
➢一定要注意结束条件。
例如,计算n!的问题
➢可以将其分解为:n! = n*(n-1)!
➢分解后的子问题(n-1)!与原问题n!的计算方法完全一样,只是
规模有所减小;
➢(n-1)!这个子问题又可以进一步分解为(n-1)*(n-2)!,(n-2)!可
以进一步分解为(n-2)*(n-3)!…
➢直到要计算1!时,直接返回1。
fac(5)的计算过程如下:
fac(5)=>5*fac(4)
def fac(n): =>5*(4*fac(3))
if n==1: =>5*(4*(3*fac(2)))
return 1 =>5*(4*(3*(2*fac(1))))
return n*fac(n-1)
=>5*(4*(3*(2*1)))
print(fac(5)) =>5*(4*(3*2))
=>5*(4*6)
=>5*24
=>120
def gcd(a,b):
r = a%b
求最大公约数 if r == 0:
return b
else:
return gcd(b,r)
Demo:输出下面列表中的数字
ls=[1, 2, [3, [4, 5, 6, [7, 8, [9, 10, [11,
12, 13, [14, 15,[16,[17,]],19]]]]]]]
def search(ls):
for item in ls:
if type(item) is list:
search(item)
else:
print(item)
search(ls)
1 变量的作用域
2 匿名函数
3 递归函数
课程目录 4 闭包
Course catalogue
输出:
def test(): testing
print("testing") <function test at
0x0000019C9BB901E0>
test() 分析:print(test)输出了test函数对
print(test) 象地址,但并没有调用test函数。
def test(): 输出:
print("testing") <function test at
0x00000211251F01E0>
testing
test2= test
print(test2) 分析:赋值成功,test2 指向
test2() 了test函数
在函数操作中,函数也可以当成一个参数或一个
返回值进行返回, 当程序内或程序外拿到函数的引
用后就可以直接使用这个函数。
如果内层函数使用了外层函数中定义的局
部变量,并且外层函数的返回值是内层函数的
引用,就构成了闭包。
<function outer.<locals>.inner at
def outer(x):
0x000001524E2735E0>
y=10
def inner(z): outer f=inner
return x+y+z x=5 x
return inner
y=10 y
f=outer(5)# f=inner inner z
print(f) Traceback (most recent call last):
print(inner(20))
File "C:\python\a.py", line 10, in <module>
print(inner(20))
NameError: name 'inner' is not
defined
outer f=inner
def outer(x): x=5 x
y=10 y=10 y
def inner(z): inner z=20
return x+y+z
return inner f(20)
->outer(5)(20)
f=outer(5) ->inner(20)#x=5,y=10,z=20
print(f(20)) f(20)的值为: 5+10+20=35
print(outer(5)(20)) 通过f函数访问了outer函数
的内部变量
outer f=inner
def outer(x):
y=10 x=5 x
def inner(z): y=50 y
return x+y+z inner z=20
y=50
return inner f(20)
->outer(5)(20)
f=outer(5) ->inner(20)#x=5,y=50,z=20
print(f(20))
f(20)的值为: 5+50+20=75
如果要修改外部变量的值,需要将变量声明为 nonlocal
➢ 让函数内部的局部变量始终保持在内存中;
Python闭包的__closure__属性
闭包比普通的函数多了一个 __closure__ 属性,
该属性记录着自由变量的地址。当闭包被调用时,系
统就会根据该地址找到对应的自由变量,完成整体的
函数调用。
print(f.__closure__)
(<cell at 0x000001D5D81993D0: int object at
0x000001D5D5B36C30>,
<cell at 0x000001D5D8199C70: int object at
0x000001D5D5B36A50>)
下面代码的功能是,采用闭包定义n 次幂函数,再得到计
算平方的函数my_square
def nth_power(n):
def exponent_of(num): num**n
return ________ exponent_of
return _________ 2
my_square(5)
#my_square为计算一个数的平方的函数
my_square = nth_power(_________)
#计算5的平方
print(____________________)
生成器函数利用关键字yield一次返回一个结果;每次请
求一个值,就会执行生成器中的代码,直到遇到一个yield。
def fibo():
g=fibo()
a, b = 1, 1
while True:
print(next(g)) 1
yield a print(next(g)) 1
a, b = b, a + b print(next(g)) 2
g.send() g.close()
1
1
g=fibo()
def fibo(): 2
for f in g: 3
a, b = 1, 1
print(f) 5
while True: 8
if f > 100:
yield a 13
g.close() 21
a, b = b, a + b
break 34
55
89
144
import turtle
import turtle import turtle
bob = turtle.Turtle()
bob = turtle.Turtle() bob = turtle.Turtle()
def square(t, n, length):
def square(t): def square(t, length):
angle = 360 / n
for i in range(4): for i in range(4):
for i in range(n):
t.fd(100) t.fd(length)
t.fd(length)
t.lt(90) t.lt(90)
t.lt(angle)
square(bob) square(bob,150)
square(bob,7,90)
turtle.mainloop() turtle.mainloop()
turtle.mainloop()
>>>def average(a, b, c):
"""
该函数用于计算三个数的平均值,并返回一个结果
:param a: int_第一个数
:param b: int_第二个数 >>>print(average.__doc__)
:param c: int_第三个数 该函数用于计算三个数的平均
:return: 返回一个计算结果 值,并返回一个结果
""" :param a: int_第一个数
d = (a + b + c) // 3 :param b: int_第二个数
print("平均数为:", d) :param c: int_第三个数
return d :return: 返回一个计算结果
>>>help(average)
注释信息作为函数的帮助说明。
def gcd(a,b):
if not isinstance(a, int):
print('a is not a integer.')
return None
elif not isinstance(b, int):
print('b is not a integer.')
return None
elif a<=0 or b<=0:
print('a or b is not a negative integer.')
return None
r = a%b
if r == 0:
return b
else:
return gcd(b,r)
(1)变量作用域规定了变量起作用的代码范围。通常,在函数体中使用的变量为
局部变量,在函数体外使用的变量为全局变量。通过global关键字,可以在函数
内定义或者使用全局变量。
(2)lambda表达式相当于只有一条return语句的函数,作为另一个函数的参数。
(3)递归调用是函数调用自身的一种特殊应用。递归必须要有边界条件,即递归
终止的条件。
(4)闭包是由函数及其相关的引用环境组合而成的实体,是引用了自由变量的函
数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环
境也不例外。
print([f() for f in [lambda: d for d in [1,2]]])