1.上周回顾
1)、函数名的应用
直接打印函数名,是函数的地址
变量
函数的参数
函数的返回值
可以当容器类数据类型的元素
2)、闭包
内层函数对外层函数的非全局变量的引用,就是闭包。
并返回内部函数或其结果给外部。
3)、装饰器
import time from functools import wraps def wrapper(f): @wraps(f) def inner(*args, **kwargs): # inner.__name__ = f.__name_ #print(inner.__closure__) print('login执行前!', f.__name__) ret = f(*args, **kwargs) print('login执行后!') return ret return inner
2.函数的有用信息
函数名.__name__
函数名.__doc__
def login(username,password): """ 这是一个登陆函数,有两个参数 :param username: :param password: :return: """ print('登陆成功。。。。。') print(login.__name__) print(login.__doc__)
3.带参数的装饰器
import time def timer_out(flag): def timer(f): def inner(*args, **kwargs): ##### if flag: start_time = time.time() time.sleep(0.3) ret = f(*args, **kwargs) end_time = time.time() print('用时%s秒!'% (end_time-start_time)) ###### return ret else: ret = f(*args, **kwargs) return ret return inner return timer flag = False @timer_out(flag) def login(username,password): """ 这是一个登陆函数,有两个参数 :param username: :param password: :return: """ print('登陆成功。。。。。') login(1,2)
4.多个装饰器装饰一个函数
恰当的描述就是俄罗斯套娃!!
from functools import wraps def wrapper1(f): @wraps(f) def inner1(*args, **kwargs): print('wrapper1,login执行前!') ret = f(*args, **kwargs) print('wrapper1,login执行后!') return ret return inner1 def wrapper2(f): @wraps(f) def inner2(*args, **kwargs): print('wrapper2,login执行前!') ret = f(*args, **kwargs) print('wrapper2,login执行后!') return ret return inner2 @wrapper2 #login = wrapper1(inner1) ==inner2 login更新变量 @wrapper1 #login = wrapper1(login) ==inner1 login新变量 def login(): print('登陆成功!!!') login() """ 运行结果: wrapper2,login执行前! wrapper1,login执行前! 登陆成功!!! wrapper1,login执行后! wrapper2,login执行后! """
5.global和nonlocal的进一步解析和总结
局部作用域只能引用全局变量而不能修改,如要修改,必须要先声明global,同一层级作用域,全局变量的声明要放在最上面,否则会引起错误。
子函数只能引用父函数的变量,而不能修改,如要修改,要nonlocal下。
def f1(): global x print(x) # x = 15 # print(x) def f2(): global x x =100 print(x) f2() print(x) # global x x = 300 print(x) f1() print(x)
6.作业讲解收获知识点
如果一个函数的默认参数是可变数据类型(如列表[]),无论使用多少次默认参数,都是一个。
def extendlist(var ,li=[]): li.append(var) return li list1 = extendlist(10) list2 = extendlist(123,[]) list3 = extendlist('a') print(list1) print(list2) print(list3) """ 运行结果: [10, 'a'] [123] [10, 'a'] """
这个例子中函数第一次执行时,默认参数li = []是局部变量,执行完成后return后应该是li全局变量,赋值给list1就是全局变量了吧。
7.预习和拓展:
迭代器和生成器:
可迭代对象:
拥有__iter__方法,惰性运算,range()、str、list、tuple、set、dict
迭代器:拥有__iter__方法和__next__方法,
iter(range()),iter(str),iter(list),iter(tuple),iter(dict),iter(set),reversed(list_o),map(func,list_o),filter(func,list_o),file_o
生成器表达式和生成器函数:
列表推导式中的【】换成()就是生成器表达式
函数中有yield和yield from的就是生成器函数。