过了元旦,加油鸭,冲鸭!!!闭包
闲话不说,开始今日份学习整理。函数
今日目录,今天的学习内容不是不少!学习
1.函数名的运用spa
2.闭包(重要)code
3.迭代器(重要)对象
开始今日份总结blog
1.函数名的运用内存
1.1函数名是一个特殊的变量utf-8
def func(): print(666) print(func) #结果 <function func at 0x000001C2D44E7F28> #返回函数的内存地址
1.2函数名能够当作变量赋值it
def func(): print(666) func2 = func f1 = func2 f2 = f1 f3 = f2 print(f3) #结果,返回函数的内存空间 <function func at 0x0000020FA58B7F28>
1.3函数名能够当作容器类数据类型的元素
def func1(): print('func1') def func2(): print('func2') def func3(): print('func3') li =[func1,func2,func3] for i in li: i() #这样就能够一个一个的去调用函数了
1.4函数名能够当作函数的参数
def func(x): x() print('in func') def func1(): print('in func1') func(func1) #结果 in func1 in func
1.5函数名能够当作函数的返回值
def func(x): # x ---> func1 return x # func1 def func1(): print('in func1') ret = func(func1) # func1 ret() #结果 in func1
2.闭包(重要)
定义:
闭包的肯定
#不是闭包 name = 'test' def func1(): def inner(): print(name) return inner() f = func1() print(f.__closure__[0].cell_contents) #结果 AttributeError: 'NoneType' object has no attribute '__closure__' #表示函数内没有闭包的参数 #是闭包 # 闭包 def func(): age =18 name ='test' def inner(): print(age) print(name) return inner f = func() # 获取闭包引用的外层变量 print(f.__closure__[0].cell_contents) print(f.__closure__[1].cell_contents) #结果 18 test
闭包的用法
需求,输入一个数,连续自加这个数五次,有可能会写成这样
def func(step): sum = 1 sum += step print(sum) i =0 while i <5: func(3) i+=1 #结果 4 4 4 4 4
闭包:解释器执行程序时,若是遇到函数,随着函数的结束而关闭临时名称空间,可是!!!
若是遇到闭包,有一个机制:那么闭包的空间不会随着函数的结束而关闭。
从新写一下上面这个需求
def func(step): sum1 = 1 def inner(): nonlocal sum1 sum1 += step print(sum1) return inner i =0 f =func(3) while i <5: f() i+=1 #结果 4 7 10 13 16
须要注意的是,若是将f =func(3)放入下面循环内部,就会发现打印的都是4,缘由呢,就是生产了五个闭包,每一个闭包执行了一次。
闭包的经常使用使用环境
3.迭代器(重要)
3.1可迭代对象
经常使用可迭代对象为:str list tuple set range() 文件句柄
可迭代对象:内部含有__iter__方法的就是可迭代对象,遵循可迭代协议,可迭代对象不能直接取值
判断是不是可迭代对象
# 方法一:
s1 = 'barry'
# print('__iter__' in dir(s1))
# print('__iter__' in dir(range(10)))
3.2迭代器
迭代器:内部含有'__iter__'而且含有'__next__'方法的就是迭代器,遵循迭代器协议。
可迭代对象转化成迭代器
可迭代对象.__iter__() 或者 iter(可迭代对象)
s1 = 'abcd' obj = iter(s1) print(obj) print(obj.__next__()) print(obj.__next__()) print(obj.__next__()) print(obj.__next__()) print(obj.__next__()) # 一个next 对应一个值,一一对应。 #结果 a b c d print(obj.__next__()) StopIteration
判断
一个对象是是迭代器
#方法一:判断一个对象内有没有指定的方法 li =[1,2,3,4] obj = iter(li) print('__iter__'in dir(obj) and '__next__'in dir(obj)) #结果 True #方法二:引入其余模块,进行判断 from collections import Iterable from collections import Iterator li =[1,2,3,4] obj = iter(li) print(isinstance(obj,Iterable))#判断是不是可迭代对象 print(isinstance(obj,Iterator))#判断是不是迭代器 #结果 True True #这个也能够用于判断上面是不是可迭代对象
type() isinstance()区别?
type()只是判断该对象的数据类型
isinstance()不只能够判断该对象的数据类型,并且能够判断其余不少
迭代器的做用:
1,节省内存.
2,惰性机制.
3, 一条路走到黑,不走回头路.
s2 = [1, 2, 3, 4, 5]
obj2 = iter(s2)
print(next(obj2))
print(next(obj2))
练习
# 练习 # 判断一个对象是不是可迭代对象,迭代器 # str list tuple set dict range() 文件句柄 # f = open('file',encoding='utf-8',mode='w') # print(isinstance(f,Iterator)) # s2 = [1, 2, 3] # # 将s2转化成迭代器 进行取值 # obj2 = iter(s2) # # print(obj2.__next__()) # print(next(obj2)) #while循环模拟for循环机制