一、函数名的应用
1、函数名就是函数的内存地址
def func(): print(666) func() print(func) #函数的内存地址
2、函数名可以作为变量
def func1(): print(666) f1 = func1 f2 = f1 f2() #执行结果为 666
3、函数名可以作为函数的参数
def func1(): print(666) def func2(x): x() func2(func1)
4、函数名可以作为函数的返回值
def wraaper(): def inner(): print('in the inner') return inner ret = wraaper() ret()
5、函数名可以作为容器类类型的元素
def func1(): print('in zhe func1') def func2(): print('in the func2') def func3(): print('in the func3') def func4(): print('in the func4') l1 = [func1,func2,func3,func4] for i in l1: i()
以上函数名这种为:第一类对象
1、可以运行期创建
2、可用作函数参数或返回值
3、可以存入变量的实体
globals() # 返回全局变量的一个字典
locals() # 返回当前位置的局部变量的字典
def func1(): a = 2 b = 3 print(globals()) print(locals()) def inner(): c = 5 d = 6 print(globals()) # 全局变量的字典 print(locals()) # {'b': 3, 'a': 2} inner() print(globals()) # 全局变量的字典 print(locals()) # {'d': 6, 'c': 5} func1()
二、闭包
2.1 闭包的作用:当程序执行时,遇到了函数执行,他会在内存中开辟一个空间,局部名称空间.如果函数内部形成了闭包,那么他就不会随着函数的结束而消失。
举例爬虫闭包:
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()
2.2 什么是闭包? 内层函数对外层函数的变量(非全局变量)的引用,并返回。这样就形成了闭包
def wraaper(): name = 'alex' # 引用非全局变量 def inner(): print(name) print(inner.__closure__) # (<cell at 0x00000223146565E8: str object at 0x000002231461A768>,) inner() # 说明是一个闭包 return inner wraaper()
name = 'alex' # 引用全局变量 def wraaper(): def inner(): print(name) print(inner.__closure__) # None,引用了全局变量,所以不是闭包 inner() return inner wraaper()
三、迭代器
3.1.1 可迭代对象
for i in 'abc': print(i) for i in 123: print(i) #'int' object is not iterable 整数不是可迭代对象
注:可迭代对象:str、list、dict、tuple、set、rang()
3.1.2 判断一个对象是否是可迭代对象:
第一种方法:
s1 = [1,2,3] print('__iter__'in dir(s1)) # True
第二种方法:
from collections import Iterable print(isinstance('alex',Iterable)) # True
引导:这个方法还可以判断数据是什么数据类型
from collections import Iterable print(isinstance('alex',str)) # True
3.2.1迭代器
判别方法:对象内部含有__iter__方法且含有__next__方法就是迭代器。
f = open('regsiter',encoding='utf-8') print('__iter__' in dir(f)) # True print('__next__' in dir(f)) # True f.close()
3.2.2 可迭代对象——>>(转化成)迭代器
lis = [1,2,3] # 可迭代对象 itel = lis.__iter__() # 迭代器<list_iterator object at 0x0000020750163DD8> # itel = iter(lis) # 迭代器<list_iterator object at 0x0000020750163DD8> print(itel)
3.2.3 迭代器如何取值? next一次,取一个值
lis = [1,2,3] # 可迭代对象 itel = lis.__iter__() #(转化成)迭代器
print(itel.__next__()) print(itel.__next__()) print(itel.__next__())
3.2.4 可迭代对象与迭代器的区别
1、可迭代对象不能取值,迭代器是可以取值的
2、迭代器非常节省内存。
3、迭代器每次只会取一个值。
4、迭代器是单向的,一条路走到头
3.2.5 while 循环模拟for循环
for 循环
l1 = 'abcdefg' for i in l1: print(i)
while 循环模拟for循环
l1 = 'abcdef' l = l1.__iter__() # 将可迭代对象转换成迭代器 while 1: try: print(l.__next__()) # 调用__next__()方法取值 except StopIteration: # 利用异常处理停止报错 break