一.函数名的运用
1.函数名的内存地址
1 def func(): 2 print("英雄联盟") 3 print(func) 4 #输出结果: 5 <function func at 0x00000299E4C62E18> 6 #证明这个函数名func就是一块内存地址
若func直接赋值给a,则a也指向这块内存地址,所以a()进行了函数调用,执行a()结果为"英雄联盟"
2.函数名当做容器类的元素
def func1(): print("吃") def func2(): print("喝") def func3(): print("拉") lst = [func1,func2,func3] for i in lst: i() #输出结果: 吃 喝 拉
a:当列表中的元素func1改为func1()时,会牵扯到返回值的问题
1 def func1(): 2 print("吃") 3 def func2(): 4 print("喝") 5 def func3(): 6 print("拉") 7 lst = [func1(),func2(),func3()] 8 print(lst) 9 #输出结果 10 吃 喝 拉 11 [None, None, None] #看这里 12 每一个函数都会被执行,但是返回值都为空;
b:函数可以作为参数,传递给另一个函数:
1 def func(fn): 2 fn() 3 def gn(): 4 print("穿靴子的猫") 5 func(gn) 6 #输出结果 7 穿靴子的猫
c:函数也可以作为返回值被执行;所以综上函数就是一个变量;
3.闭包
a:闭包的概念:内层函数,对外层函数(非全局)的变量的引用,叫闭包;
代码展示:
1 def func(): 2 name = "alex" 3 print(1111) 4 def gn(): 5 print(name) 6 return gn 7 ret = func() 8 ret() #这里是直接调用了gn函数,因为输出结果表示没有执行print(111) 9 ret() #所以直接调用gn的时候,如果外部函数的变量name被清除,那将会报错 10 ret() #所有外层函数name会常驻内存; 11 #输出结果 12 1111 13 alex 14 alex 15 alex
#爬虫的一个小程序
1 from urllib.request import urlopen 2 def but(): 3 content = urlopen("http://www.xiaohua100.cn/index.html").read() 4 def get_contend(): 5 return content 6 print(get_contend.__closure__) #这句话是判断该函数是不是闭包 7 return get_contend 8 fn = but() 9 content = fn() 10 print(content) 11 12 content2 = fn() 13 print(content2) 14 #如果输出None,则表示它不是闭包, 15 若是,则输出一串地址:(<cell at 0x0000025ED7A88678: bytes object at 0x0000025ED7E95330>,)
二.迭代器
1.可迭代对象:list,str,tuple,set,f,dict,这几个对象当中,都有一个函数__iter__()
a:可以用dir方法查看数据类型包含了哪些东西;格式:print(dir(数据类型))
1 print("__iter__" in dir(list)) 2 print("__iter__" in dir(tuple)) 3 print("__iter__" in dir(str)) 4 print("__iter__" in dir(dict)) 5 print("__iter__" in dir(set)) 6 print("__iter__" in dir(int)) #不可迭代对象 7 #输出结果: 8 True 9 True 10 True 11 True 12 True 13 False
b:迭代器和可迭代对象的区别
1 l = [1,2,3] 2 it = l.__iter__() #it为迭代器 3 from collections import Iterable #导入模块 4 from collections import Iterator 5 print(isinstance(l,Iterator)) #判断是否是迭代器 6 print(isinstance(l,Iterable)) #判断是否是可迭代对象 7 print(isinstance(it,Iterator)) 8 print(isinstance(it,Iterable)) 9 #输出结果 10 False 11 True 12 True 13 True
迭代器,内部包含了一个函数__next__(),相当于一个班的班长,负责让学生一个一个的出来;
它有个惰性机制,就是你开始让学生出去了,班长才开始一个一个的喊,你没喊开始,学生就一直在
班级里面,虽然程序已经写出来了,但是就是放在那,等你喊开始;
b:for循环的一个模拟:内部是如何执行的
1 ls = [1,2,3] 2 it = ls.__iter__() 3 while 1: 4 try: 5 count = it.__next__() #如果你没有下面的输出语句,这一句话是不会被执行的,惰性机制 6 print(count) 7 except StopIteration: 8 break 9 #输出结果;1,2,3
1)先利用可迭代对象得到迭代器, 2)然后再利用.__next__()执行可迭代对象,把值赋给变量;
c:迭代器的特点;节省内存,惰性机制,不能反复,只能向下执行;
#迭代器和while循环的最大区别就是惰性机制;