1、函数名的应用
#函数名就是一个内存地址,就是一个变量
应用1:赋值
应用2:可作为参数传递给另一个函数
应用3:可作为函数的返回值
eg. def f1():
def f2():
print("哈喽")
return f2
ret = f1() #执行f1函数获取到返回值f2函数
print(ret) #打印f2函数,是f2函数的内存地址
ret() #执行f2函数
2、闭包
2.1 闭包概念:内层函数对外层函数变量(非全局变量)的引用,叫闭包
eg. def f1():
name = 'alex'
def f2():
print(name) #在内层函数中调用外层函数的变量,闭包
print(f2.__closure__) #判断f2是不是闭包,若打印为None就不是闭包
#是闭包会打印类似信息如:(,)
return f2
ret = f1()
ret()
2.2 闭包作用:
1)检查到是闭包函数时,函数执行结束空间不会立马释放。让局部变量name常驻内存,提高效率
2)相比较全局变量(可通过global修改不安全),使用闭包防止被其他程序修改,仅活动在当前函数下
3、迭代器
list1 = [1,2,3]
print(dir(list1))
# dir()来查看一个对象,数据类型中包含了哪些东西
#若包含了__iter__()的数据类型那么就是可迭代的数据类型 Iterable
可迭代对象: str, list, tuple, set, f, dict
# 所有的以上数据类型中都有一个函数__iter__(),表可迭代的
#判断是不是可迭代对象:
s = "王尼玛"
print("__iter__" in dir(s)) #True
print("__iter__" in dir(list1)) #True
print("__iter__" in dir(123)) #False
举例:
list2 = ["皇阿玛", "皇额娘", "容嬷嬷", "紫薇"]
it = lst.__iter__() # 生成迭代器
#迭代器往外拿元素. __next__()
print(it.__next__()) # 皇阿玛
print(it.__next__()) # 皇额娘
print(it.__next__()) # 容嬷嬷
print(it.__next__()) # 紫薇
print(it.__next__()) # 迭代到最后一个元素之后. 再进行迭代就报错了
通过 StopIteration 异常标识迭代的完成
# 模拟for循环实现:
lst = ["皇阿玛", "皇额娘", "容嬷嬷", "紫薇"]
it = lst.__iter__() #获取迭代器
while True:
try:
name = it.__next__() #使用迭代器进行迭代,获取第一个元素
print(name)
except StopIteration: # 拿完了
break
判断xx对象是不是可迭代的:
lst = [1, 2, 3]
方法一:
print("__iter__" in dir(lst)) # 确定是不是可迭代的,True
print("__next__" in dir(lst)) # 确定是不是一个迭代器,False
方法二:
from collections import Iterable # 可迭代的
from collections import Iterator # 迭代器
# isinstance(对象, 类型) 判断xx对象是否是xxx类型的
print(isinstance(lst, Iterable))
print(isinstance(lst, Iterator))
#可迭代对象里 str, list, tuple, set, f, dict,只有f文件句柄是迭代器
总结:
1、可迭代对象: str list tuple f dict set
2、生成迭代器: it = lst.__iter__()
3、迭代器取数据: it.__next__()
4、可迭代对象一定是包含__iter__()的,迭代器一定包含__iter__()和__next__()
5、迭代器的作用:
1)节省内存
2)惰性机制
3)只能往下执行,不能反复