python note 11 函数名的使用、闭包、迭代器
1、函数名就是一个变量
def func(): print("我是一个小小的函数") a = func print(a) #输出变量存放地址 <function func at 0x00000251AD780048> func() #func()等同于a(),输出 我是一个小小的函数
2、函数名是变量名
def func1(): print("我是1") def func2(): print("我是2") def func3(): print("我是3") lst = [func1, func2, func3] for el in lst: el() #输出 我是1 我是2 我是3
3、函数名可以作为参数传递给函数
def my(): print("我是my") def proxy(fn): # 代理模式. 装饰器 print("在处理之前") fn() print("在处理之后") proxy(my) # 把函数名作为参数传递给另一个函数 #输出 在处理之前 我是my 在处理之后
def func1(): print("我是func1") def func2(): print("我是func2") def func(fn, gn): # 函数名可以作为参数进行传递 print("我是func") fn() gn() print("哈哈哈") func(func1, func2)
func()()用法
def func(): print("我是func") a = 10 # 变量 def inner(): print("我是inner") return inner ret = func() ret() func()() # 先运行func() 然后在返回值上加(),等于上一个写法 #输出 我是func 我是inner
4、闭包
#闭包. 在内层函数中访问外层函数的变量
# 闭包的作用:
# 1. 可以保护你的变量不收侵害
# 2. 可以让一个变量常驻内存
如果不闭包全局变量是不安全的
a = 10 # 不安全的 def outer(): global a a = 20 def outer_2(): global a a = 30 outer_2() outer() print(a) #输出 20 #如果交换outer_2()和outer(),那么输出会变为30
闭包变量会常驻内存
def outer(): a = 10 # 常驻内存, 为了inner执行的时候有值. def inner(): print(a) return inner fn = outer() fn() # 调用的时机是不定的. #输出 10
超简易爬虫
from urllib.request import urlopen def outer(): # 常驻内存 s = urlopen("http://www.xiaohua100.cn/index.html").read() def getContent(): # 闭包 return s return getContent print("爬取内容.....") pa = outer() ret = pa() print(ret)
查看是否闭包
def func(): a = 10 def inner(): print(a) print(inner.__closure__) func() # 如果打印的是None. 不是闭包. 如果不是None, 就是闭包
5、迭代器
# dir查看xx类型的数据可以执行哪些方法 print(dir(str))、print(dir(list))、print(dir(int))
# 所有的带__iter__可以使用for循环的, 可迭代对象。print(dir(int)) 没有__iter__
# 可迭代对象可以使用__iter__()来获取到迭代器 # 迭代器里面有__next__() # s = "石可心喜欢赵一宁" # it = s.__iter__() # 获取迭代器 # print(dir(it)) # 迭代器里有__iter__ 还有__next__
迭代器特性
# 1. 只能向前.
# 2. 几乎不占用内存, 节省内存(需要明天生成器)
# 3. for循环
# 4. 惰性机制 (面试题,难度系数比较高)
s = "石可心喜欢赵一宁" it = s.__iter__() # 获取迭代器 print(it.__next__())# 石 print(it.__next__())# 可 print(it.__next__())# 心 print(it.__next__())# 喜 print(it.__next__())# 欢 print(it.__next__())# 赵 print(it.__next__())# 一 print(it.__next__())# 宁
迭代器模拟for循环
lst = ["赵一宁", "石可心", "朱奎峰", "姚明","潘长江"] for el in lst: # 底层用的是迭代器 print(el)
不输出错误
lst = ["赵一宁", "石可心", "朱奎峰", "姚明","潘长江"] it = lst.__iter__() # 获取迭代器 while 1: try: # 尝试执行 el = it.__next__() # 获取下一个元素 print(el) except StopIteration: # 处理错误,不显示 break
判断是否为迭代器
偏方
# print("__iter__" in dir(it)) # print("__next__" in dir(it)) # 可以通过dir来判断数据是否是可迭代的, 以及数据是否是迭代器
官方方案
# from collections import Iterable # 可迭代对象 # from collections import Iterator # 迭代器 # # print(isinstance(lst, Iterable)) # print(isinstance(lst, Iterator)) # # print(isinstance(it, Iterable)) # print(isinstance(it, Iterator))