内容大纲:
一、函数名的应用
二、globals()、locals()
三、闭包
四、迭代器
一、函数名的应用
1、函数名就是函数的内存地址,直接打印函数名,就是打印内存地址
def func1(): print(123) print(func1) 结果: <function func1 at 0x0000029042E02E18>
2、函数名可以作为变量
def func1(): print(111) f = func1 f() #f()就是func1()
3、函数名可以作为函数的参数
def func1(): print(111) def func2(x): x() func2(func1) #func1作为func2的参数
4、函数名可以作为函数的返回值
def wrapper(): def inner(): print('inner') return inner f = wrapper() f()
5、函数名可以作为容器类类型的元素
def func1(): print('func1') def func2(): print('func2') def func3(): print('func3') l1 = [func1,func2,func3] for i in l1: i()
像上面函数名这种,叫做第一类对象:
可以在运行时创建
可以作函数的参数和返回值
可存入变量的实体
二、golbals()、locals()
globals():返回全局变量的字典
locals():返回当前位置的局部变量的字典
def func(): a = 1 b = 2 print('func',globals()) print('func',locals()) def func1(): c = 3 d = 4 print('func1',globals()) print('func1',locals()) func1() func() 执行结果: func {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000017268BFA400>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'C:/python/8.17day11/代码量-翁惠天-8.17.py', '__cached__': None, 'func': <function func at 0x0000017268AF2E18>} func {'b': 2, 'a': 1} func1 {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000017268BFA400>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'C:/python/8.17day11/代码量-翁惠天-8.17.py', '__cached__': None, 'func': <function func at 0x0000017268AF2E18>} func1 {'d': 4, 'c': 3}
三、闭包
1、什么是闭包:内层函数对外层函数变量(非全局变量)的引用,并返回内层函数名,就形成了闭包
2、闭包的作用:爬虫、装饰器
当程序执行遇到函数执行时,会在内存空间开辟局部命名空间,当函数执行完毕,该命名空间会被销毁。但是如果这个函数内部形成闭包,则该内存空间不会随着函数执行完而消失。
3、如何判断是否是闭包:print(函数名.__closure__)结果是cell说明是闭包,结果是None说明不是闭包
def func(): name = 'hello' def inner(): print(name) inner() print(inner.__closure__) return inner func() 结果是: hello (<cell at 0x000002A81BBB85E8: str object at 0x000002A81BC51AB0>,)
四、迭代器
1、可迭代对象:对象内部含有__iter__方法就是可迭代对象,例如 str、list、dict、tuple、set、range()
判断方法:两种
①print('__itr__' in dir(对象))
②from collections import Iterable
print(isinstance(对象,Interable))
#方法1: print('__iter__' in dir('alex')) # 方法二 from collections import Iterable print(isinstance('alex',Iterable)) 结果是:True
2、迭代器:对象内部含有__iter__和__next__方法就是迭代器,文件句柄就是迭代器。
判断方法:
①print('__iter__' in dir(对象))
print('__next__' in dir())
两个都必须是True
② from collection import Iterator
print(isinstance(对象,Iterator))
#方法1: with open('a', encoding='utf-8') as f1: print('__iter__'in dir(f1)) print('__next__'in dir(f1)) # 方法2: from collections import Iterator print(isinstance(f1,Iterator)) 结果是:True
3、可迭代对象VS迭代器
① 可迭代对象不能取值,迭代器是可以取值的。可迭代对象可以转化成迭代器
l1 = [1,2,3]
# 方法1: ite1 = l1.__iter__() # 方法2: ite2 = iter(l1)
②迭代器非常节省内存
③迭代器每次只会取一个值
l1 = [1,2,3] ite1 = l1.__iter__() print(ite1.__next__()) #每次只打印一个元素 print(ite1.__next__()) #打印第二个元素
④迭代器是单向的,不反复
4、for循环的内部运行机制
① 将可迭代对象转化为迭代器
② 调用__next__方法取值
③ 利用异常处理机制停止报错
s1 = 'sadda' ite1 = iter(s1) while 1: try: print(ite1.__next__()) except StopIteration: break