一、函数名的使用
一、函数名的使用
返回值 函数名 (返回函数名的时候不能加括号)
函数名可以当容器的元素
函数名可以当做参数被传递
def func(): print('func') def func1(): return func # 将函数名func作为返回值,返回给了func1() func1()()
def func1(): print('这是func1') def func2(): print('这是func2') def func3(): print('这是func3') li = [func1,func2,func3] for i in li: i() 这是func1 这是func2 这是func3 当容器的元素
def func(): print('这里打印 func') def test(k): k() test(func) # 将函数名当作参数传递
二、闭包
一、什么是闭包
1、首先又一个嵌套函数
2、嵌套函数的内部函数调用非全局的变量
3、将内部函数名当作返回值返回、在全局调用
二、怎么查看闭包?
1、函数名.__closure__返回None 就不是闭包
三、闭包的特点
1、保护变量
2、可以让一个变量常驻内存(比如爬虫、不用每次都去重新请求网页)
四、闭包的应用
1、和全局变量一样,他不确定什么时间会被调用,所以会常驻内存,随时等候被调用,例如:爬虫、第一次请求就会把你想要的数据常驻内存中、方便呢以后调用;
五、闭包函数示例
def test(): url = 'www.baidu.com' def func(): print(url) # 引用外部作用域的变量 return func # 返回func的内存地址 res = test() res() # www.baidu.com print(test()) # <function test.<locals>.func at 0x0000021AE401A950> def func1(): a = 10 def func2(num): nonlocal a # 可以通过关键字进行修改 a += num print(a) return func2 func1()(100) 查看是否是闭包函数,打印结果不是None就是闭包
三、迭代器
一、什么是迭代器
具有__iter__方法就是可迭代对象 li = [1,2,3] a = li.__iter__() li具有__iter__方法,所以是可迭代对象
二、什么是迭代器
同时具有__iter__方法和__next__方法的就是迭代器 for循环的机制 就是迭代器; #优点: # - 提供一种统一的、不依赖于索引的迭代方式 # - 惰性计算,节省内存 #缺点: # - 无法获取长度(只有在next完毕才知道到底有几个值) # - 一次性的,只能往后走,不能往前退
1 li = [1,2,3] 2 a = li.__iter__() 3 print(a.__next__()) 4 print(a.__next__()) #一个一个取 5 print(a.__next__()) 6 print(a.__next__()) #将可迭代对象内的元素全部取完后在取会抛出'StopIteration'
1 li = [1,2,3,4,6,7,87,8,9,90,0,0,0,0,8,7,7,67,] 2 em = li.__iter__() 3 while 1: 4 try: 5 print(em.__next__()) 6 7 except StopIteration: 8 break 9 10 当出现 StopIteration 直接退出循环 11 12 异常捕获
四、递归
在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数,记住哦->在函数内部调用其他函数不是函数的嵌套,而在函数内部定义子函数才是函数的嵌套;
举个例子,我们来计算阶乘n! = 1 x 2 x 3 x ... x n
,用函数fact(n)
表示,可以看出:
fact(n) = n! = 1 x 2 x 3 x ... x (n-1) x n = (n-1)! x n = fact(n-1) x n
所以,fact(n)
可以表示为n x fact(n-1)
,只有n=1时需要特殊处理。于是,fact(n)
用递归的方式写出来就是
def fact(n): if n==1: return 1 return n * fact(n - 1)
如果我们计算fact(5)
,可以根据函数定义看到计算过程如下:
===> fact(5) ===> 5 * fact(4) ===> 5 * (4 * fact(3)) ===> 5 * (4 * (3 * fact(2))) ===> 5 * (4 * (3 * (2 * fact(1)))) ===> 5 * (4 * (3 * (2 * 1))) ===> 5 * (4 * (3 * 2)) ===> 5 * (4 * 6) ===> 5 * 24 ===> 120
递归函数的优点
1、定义简单,逻辑清晰。理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰。
2、使用递归函数需要注意防止栈溢出。在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。可以试试fact(1000),
递归默认层次,官方说明 1000,实际测试 998/997,
3、自己玩自己的(自己调用自己本身)
4、玩的有限制(有明确的结束条件)
5、修改递归的最大层
import sys sys.setrecursionlimit(10000)
6、示例
def fun(n): print(n) if n / 2 == 0: return n res = fun(int(n/2)) return res fun(10)