函数名的使用:
函数名是一个变量, 但它是一个特殊的变量, 与括号配合可以执行函数的变量
函数名的内存地址:
def func(): pass print(func) # 函数的内存地址 结果:<function func at 0x000001C52AAEBD08>
函数名可以赋值给其他变量:
def func(): print(1) a = func a() func() # 函数名可以当做值赋值给变量 结果: 1 1
函数名可以当做容器类的元素:
def func(): print(1) def func2(): print(2) li = [func,func2] print(li) # 函数名可以当做元素放到容器里 结果:[<function func at 0x000001A17C35BD08>, <function func2 at 0x000001A17C35BD90>](打印的是函数的内存地址,列表里的函数可以加括号,打印的是函数执行的结果,及列表的返回的None) def func(): print(1) def func2(): print(2) li = [func(),func2()] print(li) # 函数名可以当做元素放到容器里 结果:1 2 [None, None]
函数名可以当做函数的参数:
def func(): print("吃了么") def func2(fn): print("我是1") fn() # 执行传递过来的fn print("我是2") func2(func) # 把函数func当成参数传递给func2的参数fn. 结果: 我是1 吃了么 我是2
函数名可以作为函数的返回值
def func_1(): print("这里是函数1") def func_2(): print("这里是函数2") print("这里是函数3") return func_2 fn = func_1() # 执行函数1. 函数1返回的是函数2, 这时fn指向的就是上面函数2 fn() # 执行func_2函数
结果:
这里是函数1
这里是函数3
这里是函数2
def func(): def aa(): print(2) return None return aa() # return None # func() # func() == None print(func()) 结果: 2 None
例题:
li = [] for i in range(3): #for循环三次,三次最终结果i=2 def func(x): #定义函数,形参为x print(x*i) #打印形参与i(2)相乘的结果 li.append(func) #将func依此添加到li列表当中,循环三次,添加三个, # 此时,列表里的func虽然外表相同,定义的函数相同,但内存地址不一样,存在三个内存地址 for func in li: #将列表里的函数循环出来 func(2) #依此执行func函数,实参数为2 结果:4 4 4 此时我要想将结果打印为0,2,4,只需定义一个数即可 li = [] for i in range(3): #for循环三次,循环为 i =(0,1,2) def func(x,y=i): #定义函数,形参为x,y=循环的 i 值 print(x*y) #打印形参与y(0,1,2)相乘的结果 li.append(func) #将func依此添加到li列表当中,循环三次,添加三个, # 此时,列表里的func虽然外表相同,定义的函数相同,但内存地址不一样,存在三个内存地址 for func in li: #将列表里的函数循环出来 func(2) #依此执行func函数,实参数为2
闭包
什么是闭包? 闭包就是内层函数, 对外层函数(非全局)的变量的引用. 叫闭包
# 1.一个嵌套函数
# 2.在嵌套函数的内部函数使用外部(非全局的变量)
# 满足以上两条就是闭包
def wrapper(): a = 10 def inner(): print(a) print(inner.__closure__) # 不是None 就是闭包 inner() wrapper() 结果: (<cell at 0x000001F6E9BF2768: int object at 0x00007FFFA5B8E470>,) 10
将里边的函数名当做参数返回给调用者
def outer(): name = "alex" # 内部函数 def inner(): print(name) return inner fn = outer() # 访问外部函数, 获取到内部函数的函数地址 fn() # 访问内部函数 结果:alex
例:
money = 10 # 全局里存放会有污染和不安全的现象 def wrapper(): money = 10 def inner(num): global money #从全局调用money money += num print(money) return inner wrapper()(100) #第二个括号是return的返回值inner的执行,实参为100
# python中闭包,会进行内存驻留, 普通函数执行完后就销毁了
# 全局里存放会有污染和不安全的现象
# 面试必问,装饰器 -- 装饰器的本质就是闭包
# 闭包有个弊端:会出现内存泄漏
迭代器
可迭代对象有哪些:str list tuple dic set
可迭代对象:可以被for的就是可迭代对象
# Python 协议
# 具有.__iter__方法的就是可迭代对象
# a = 对象.__iter__ # 创建一个迭代器
# 具有__iter__和__next__就是一个迭代器
可以for循环的就有__iter__方法,包括range
.这里的__iter__是帮助我们获取到对象的迭代器.我们使用迭代器中的__next__()来获取到一个迭代器的元素
li = [1,2,3] a = li.__iter__() print(a.__next__()) print(a.__next__()) #一个一个取 print(a.__next__()) 结果: 1 2 3
我们使用while循环和迭代器来模拟for循环: 必须要会:
lst = [6,5,4] l = lst.__iter__() while 1: try: i = l.__next__() print(i) except StopIteration #当遇到报错的时候,就break退出 break
# 迭代器特性:
# 惰性机制
# 不能从下向上走
# 一次性的,用完就没了
小总结:
Iterable: 可迭代对象. 内部包含__iter__()函数
Iterator: 迭代器. 内部包含__iter__() 同时包含__next__().
迭代器的特点:
1. 节省内存.
2. 惰性机制
3. 不能反复, 只能向下执行.
我们可以把要迭代的内容当成子弹. 然后呢. 获取到迭代器__iter__(), 就把子弹都装在弹夹中. 然后发射就是__next__()把每一个子弹(元素)打出来. 也就是说, for循环的时候.一开始的 时候是__iter__()来获取迭代器. 后面每次获取元素都是通过__next__()来完成的. 当程序遇到 StopIteration将结束循环.
递归:
# 1. 自己玩自己 (自己调用自己本身)
# 2. 玩的有限制 (有明确结束条件)
count = 0 def func(): global count count += 1 print(count) if count == 4: #当count=4时,返回 return func() #产生递归现象 func()
打印1到100
def func(n): n+=1 print(n) if n == 100: return func(n) func(0)
例题:
def func(age): print(age) #最后打印4 def func1(age): print(age) #3 func(age+1) #执行func,实参数位4 def func2(age): print(age) #2 func1(age+1) #执行func1,实参数位3 func2(2) 打印结果: 2 3 4
作业:
1.写函数,传入n个数,返回字典{‘max’:最大值,’min’:最小值} 例如:min_max(2,5,7,8,4) 返回:{‘max’:8,’min’:2}(此题用到max(),min()内置函数) 2.写函数,传入一个参数n,返回n的阶乘 例如:cal(7) 计算7*6*5*4*3*2*1 3.写函数,返回一个扑克牌列表,里面有52项,每一项是一个元组 例如:[(‘红心’,2),(‘草花’,2), …(‘黑桃’,‘A’)] 4. 相关面试题(先从纸上写好答案,然后在运行): def calc(a,b,c,d=1,e=2): return (a+b)*(c-d)+e 请分别写出下列标号代码的输出结果,如果出错请写出Error。 print(calc(1,2,3,4,5))_____ print(calc(1,2))____ print(calc(e=4,c=5,a=2,b=3))___ print(calc(1,2,3))_____ print(calc(1,2,3,e=4))____ print(calc(1,2,3,d=5,4))_____ 下面代码打印的结果分别是_________,________,________. def extendList(val,list=[]): list.append(val) return list list1 = extendList(10) list2 = extendList(123,[]) list3 = extendList('a') print('list1=%s'%list1) print('list2=%s'%list2) print('list3=%s'%list3) 5.写代码完成99乘法表.(升级题) 1 * 1 = 1 2 * 1 = 2 2 * 2 = 4 3 * 1 = 3 3 * 2 = 6 3 * 3 = 9 ...... 9 * 1 = 9 9 * 2 = 18 9 * 3 = 27 9 * 4 = 36 9 * 5 = 45 9 * 6 = 54 9 * 7 = 63 9 * 8 = 72 9 * 9 = 81