一,函数名的运用:第一类对象
函数名是一个变量,但是一个特殊的变量,与括号配合可以执行函数的变量.
1.直接打印函数名就是个内存地址:
def func(): print('哈哈') print(func) 结果:<function func at 0x0000000000864488>
2.函数名可以赋值给其他变量
def func(): print('哈哈') ret = func #把函数当成一个变量,赋值给另一个变量 ret() #函数调用func()
3.函数名可以当做容器类的元素:
def func(): print('哈哈') def func1(): print('呵呵') def func2(): print('嘿嘿') def func3(): print('嘻嘻') lst = [func,func1,func2,func3] for i in lst: i() 结果: 哈哈 呵呵 嘿嘿 嘻嘻
4,函数名可以当做函数的参数:
def func(): print('哈哈') def func1(fn): #func传递给fn print('呵呵') fn() # fn()变成了func() 所以在这里执行func()函数 print('嘻嘻') func1(func)
5.函数名可以作为函数的返回值
def func(): print('哈哈') def func1(): print('嘿嘿') print('呵呵') return func1 ret = func() #执行func()函数,打印出'哈哈',这时候ret指向fun1 ret()#即func1(),执行func1函数
二.闭包
闭包就是内层函数对外层函数(非全局)的变量的引用.
def func(): name = 'alex' def func1(): print(name) func1() func() 结果:alxe
__closure__检测函数是否是闭包,是返回cell,不是返回None.
def func(): name = 'alex' def func1(): print(name) func1() print(func1.__closure__) func()
结果: alex (<cell at 0x000000000121C078: str object at 0x0000000001202848>,)#是闭包
1.函数外面调用内部函数:
def func(): name = 'alex' def func1(): print(name) return func1 ret = func() #访问外部函数,获取内部函数的内存地址 ret() #执行内部函数
2.多层嵌套:
def func1(): def func2(): def func3(): print('嘿嘿') return func3 return func2 func1()()()
闭包的作用:1.安全,不能从函数外部去修改函数内部的变量
2.让一个变量常驻内存,供后边的程序使用,效率高
三.迭代器(Iterator) 可迭代对象:(Iterable)
可迭代对象:str list tuple dict set 文件句柄f .这些被称为可迭代对象,基于可迭代协议..
1,dir用法:
s = '哈哈哈' print(dir(s)) #可以打印对象中的方法和函数 print(dir(str)) #可以打印类中声明的方法和函数
用dir打印出来的结果如果能找到__iter__,那么这个类的对象就是一个可迭代对象.
经过dir查找,发现list,tuple,str,dict,set都有__iter__函数,range也有.这些都是可以用for循环的.
2.isinstence(对象,类型)判断xx对象是什么类型的
lst = [1,2,3] from collections import Iterable from collections import Iterator print(isinstance(lst,Iterable)) #判断是否是可迭代对象 print(isinstance(lst,Iterator) #判断是否是迭代器 结果:True False
lst = ['皇阿玛','皇后','皇太子'] it = lst.__iter__() #获取迭代器 from collections import Iterable from collections import Iterator print(isinstance(it,Iterable)) print(isinstance(it,Iterator)) 结果:True True
结论:迭代器一定是可迭代的,但可迭代的不一点是迭代器
3.判断是否可迭代的方法:
s = '哈哈哈' lst = [1,2,3] i = 123 print('__iter__'in dir(s)) #True print('__iter__'in dir(lst)) #True print('__iter__'in dir(i)) #False
4.__next__() 获取迭代器的元素
lst = ['皇阿玛','皇后','皇太子'] it = lst.__iter__() #获取迭代器 print(it.__next__()) print(it.__next__()) print(it.__next__())
注意:如果有第四个print找不到就会报错
在迭代器中有__next__()和__iter__()函数
而在可迭代对象中只有__iter__()函数 所以要确定这个可迭代对象是否是迭代器可以看是否有__next__()
5.
f = open("01",mode="r", encoding="utf-8") from collections import Iterable from collections import Iterator print(isinstance(f, Iterable)) print(isinstance(f, Iterator)) 结果:True #文件句柄既是可迭代对象有事迭代器 True
6.使用while循环 +迭代器来模拟for循环
lst = [1,2,3] lst_iter = lst.__iter__() while True: try: it = lst_iter.__next__() print(it) except StopIteration: break
迭代器特点:
1.节省内存
2.惰性机制
3.不能反复,只能向下执行