一,函数名的本质
函数名的应用:
1.函数名就是函数的内存地址
def func1(): return print(func1)
2.函数名可以作为变量
def func1(): print('hello') a = func2 b = a b()
3.函数名可以当作函数的返回值
def func1(): return func2 def func2(): print('hello') a = func1 b = a b()()
4.函数名可以当作函数的参数
def func1(x): x() def func2(): print('hello') a = func1(func2)
5.函数名可以作为容器类数据类型的元素
def func1(): print('hello-1') def func2(): print('hello-2') def func3(): print('hello-3') li = [func1,func2,func3] for i in li: i()
像上面的函数名这种,第一类对象。
第一类对象(first-class object)指 1.可在运行期创建 2.可用作函数参数或返回值 3.可存入变量的实体。
二,globals(),locals()
1.globals():返回全局变量的一个字典
2.locals():返回当前位置 局部变量的字典
def func1(): a = 3 b = 5 print(globals()) print(locals()) def func2(): a = 10 b = 20 print(globals()) print(locals()) func2() func1() print(globals()) print(locals())
三,闭包
闭包:
内层函数对外层函数的变量(非全局变量)的引用,并且外层函数返回值为内层函数名,这样就形成了闭包
def wraaper(): name = 'alex' def inner(): print(name) print(inner.__closure__) inner() return inner wraaper()
闭包作用:
当程序执行时,遇到了函数执行,他会在内存中开辟一个空间:局部名称空间,如果这个函数内层成了闭包,那么这个局部名称空间就不会随着函数的结束而消失
from urllib.request import urlopen def index(): url = "http://www.xiaohua100.cn/index.html" def get(): return urlopen(url).read() return get xiaohua = index() # get content = xiaohua() # get() content = xiaohua() # get() content = xiaohua() # get() content = xiaohua() # get() content = xiaohua() # get() content = xiaohua() # get() content = xiaohua() # get() content = xiaohua() # get() print(content.decode('utf-8'))
四,迭代器
1.可迭代对象
对象内部含有__iter__方法就是可迭代对象
可迭代对象满足可迭代协议
可迭代对象:str,list,dict,tuple,set,range()
#判断一个对象是否是可迭代对象: #第一个方法 s1 = 'alex' s2 = {'name':'alex','sex':'man'} print('__iter__' in dir(s1)) print('__iter__' in dir(s2)) #第二个方法 from collections import Iterable print(isinstance(s1,Iterable))
2.迭代器:
对象内部含有__iter__方法且含有__next__方法就是迭代器
f = open('reg',encoding='utf-8') print('_iter_' in dir(f)) #句柄是迭代器 True print('_next_' in dir(f)) # False print('_iter_' in dir(dict)) #字典是可迭代对象不是迭代器 True print('_next_' in dir(dict)) #True
3.可迭代对象vs迭代器
可迭代对象不能取值,迭代器是可以取值的
# 可迭代对象 --->(转化成)迭代器 lis = [1, 2, 3] # 可迭代对象 # ite1 = lis.__iter__() # 迭代器 <list_iterator object at 0x0000027A183BFFD0> ite1 = iter(lis) # 迭代器 <list_iterator object at 0x0000027A183BFFD0> print(ite1)
#迭代器如何取值? next一次,取一个值
print(iter1.__next__())
print(iter1.__next__())
print(iter1.__next__())
print(iter1.__next__()) #取完报错
4.总结
1.可迭代对象不能取值,迭代器是可以取值的。
2.迭代器非常节省内存
3.迭代器每次只会去一个值
4.迭代器是单方向取值的,一条路走到头
应用场景:
1.数据量非常大
2.只取值,不做其他操作时
5. while 循环模拟for循环:迭代器原理
#步骤: # 1.将可迭代对象转化成迭代器 # 2.调用__next__方法取值 # 3.利用异常处理停止报错 s1 = 'ffshf1jdoiajfkas' for i in s1: print(i) iter1 = s1.__iter__() while 1: try: print(iter1.__next__()) except StopIteration: break