函数名的本质
函数名的本质就是函数的内存地址。
函数名的应用:
- 函数名可以作为变量
def func1():
print(666)f1 = func1f1() - 函数名可以作为函数的参数
def func1(): print(666) def func2(x): x() func2(func1)
- 函数名可以作为函数的返回值
def wraaper(): def inner(): print('inner ') return inner ret = wraaper() ret()
- 函数名可以当做容器类型的元素
def f1(): print(111) def f2(): print(222) def f3(): print333) l = [f1,f2,f3] l[0]()
globals() ,locals()
globals() 返回全局变量的一个字典。
locals() 返回 当前位置 的局部变量的字典。
闭包
内层函数对外层函数的变量(非全局变量)的引用,并将函数名返回,这样就形成了一个闭包
def wraaper(): name = 'alex' def inner(): print(name) print(inner.__closure__) inner() return inner wraaper()
闭包作用:
当程序执行时,遇到了函数执行,他会在内存中开辟一个空间,局部名称空间,
如果这个函数内部形成了闭包,
那么它就不会随着函数的结束而消失。
迭代器
可迭代对象:如字符串、列表、元组、字典、集合等,对象内部含有__iter__方法就是可迭代对象.可迭代对象满足可迭代协议。
# 判断一个对象是否是可迭代对象: # 第一个方法 dic = {'name':'alex'} print('__iter__' in dir(s1)) print('__iter__' in dir(dic)) #第二种方法 from collections import Iterable from collections import Iterator print(isinstance('alex',Iterable)) print(isinstance('alex',Iterator)) print(isinstance('alex',str))
迭代器:对象内部含有__iter__方法且含有__next__方法就是迭代器.
可迭代对象 --->(转化成)迭代器
# lis = [1, 2, 3] # 可迭代对象 ite1 = lis.__iter__() ite2 = iter(lis) print(ite1,2) # 迭代器取值 next一次,取一个值 print(ite1.__next__()) print(ite1.__next__()) print(ite1.__next__()) print(ite1.__next__())
迭代器的优点:
1. 迭代器是可以取值的。(可迭代对象不能取值)
2. 迭代器非常节省内存。
3.迭代器每次只会取一个值。
4.迭代器单向的,一条路走到头。
用while模拟for循环:
# 1,将可迭代对象转化成迭代器。 # 2,调用__next__方法取值。 # 3,利用异常处理停止报错。 s1 = 'alex' iter1 = s1.__iter__() while 1: try: print(iter1.__next__()) except StopIteration: break