python 函数名称应用 闭合 迭代器 装饰器
本节无练习
=============================================
知识点概括:
1. 函数名的应用(第一类对象) 函数名的命名规范和变量是一样的. 函数名其实就是变量名, # 可以作为列表中的元素进行存储. def func1(): pass def func2(): pass lst = [func1, func2] for el in lst: el() # 可以作为参数传递给函数. def func(): pass def proxy(fn): fn() proxy(func) # 可以作为函数的返回值 def func(): def inner(): pass return inner func()() 2. 闭包 闭包:在内层函数中访问外层函数的局部变量 好处: 1. 保护你的变量不受外界影响 2. 可以让变量常驻内存 写法: def outer(): a = 10 def inner(): print(a) return inner 3. 迭代器 使用dir来查看该数据包含了那些方法 用来遍历列表,字符串,元祖....可迭代对象 可迭代对象: Iterable, 里面有__iter__()可以获取迭代器, 没有__next__() 迭代器: Iterator, 里面有__iter__()可以获取迭代器, 还有__next__() 迭代器特点: 1. 只能向前. 2. 惰性机制. 3. 省内存(生成器) for循环的内部机制. 1. 首先获取到迭代器. 2. 使用while循环获取数据 3. it.__next__()来获取数据 4. 处理异常 try:xxx except StopIteration: it = xx.__iter__() while 1: try: data = it.__next__() xxxxxx(操作) except StopIteration: break
函数名称的应用
函数名的命名规范和变量是一样的.
函数名其实就是变量名.
函数名可以做 变量 参数 返回值
引入:
1 def fun(): 2 print(1) 3 a=fun #函数赋值给a 4 print(a) # <function fun at 0x000002039C392EA0> 5 6 fun() #只有加小括号的时候才是调用 7 print(fun) #没有小括号是地址 查看函数名的地址 8 9 fun=3 #函数也是变量,可以重新赋值 函数名也是一个变量 10 print(fun) #结果为3
1) 函数名可以当做变量加入到列表中等.
1 def func1(): 2 print("我是1") 3 def func2(): 4 print("我是2") 5 def func3(): 6 print("我是3") 7 lst = [func1, func2, func3] #函数名作为变量 8 for el in lst: 9 el() # 分别执行函数 10 结果: 我是1 我是2 我是3
2) 函数名可以作为参数传递给函数
def my(): print('我是my') def proxy(fn): #代理模式.装饰器 print(1) #在处理之前 fn() print(2) #在处理之后 proxy(my) #把函数名作为参数传递给另一个函数 结果: 1 我是my 2
def func1(): print('我是func1') def func2(): print('我是func2') def func(fn,gn): print('我是func') fn() gn() print('哈哈哈') func(func1,func2)
结果: 我是func 我是func1 我是func2 哈哈哈
3) 函数名可以作为函数的返回值
1 def func(): 2 print('我是func') 3 a=10 4 def inner(): 5 print('我是inner') 6 return inner 7 ret = func() # 等于inner 8 ret() #inner() 执行inner 9 func()() # inner() 执行inner
闭包
闭包 : 在内层函数中访问外层函数的局部变量
特点 : 1. 保护变量不受侵害, (因为全局变量是不稳定的)
2. 可以让一个变量常驻内存
# 保护变量不受侵害
def outer(): a=10 #对外界是不开放的 def inner(): print(a) #内层函数方位外层函数(闭包) inner() outer() def func(): #该函数不会访问outer()中的变量 a=20 print('123')
# 常驻内存
def outer(): a=10 # 常驻内存, 为了inner执行的时候有值 def inner(): print(a) #内层函数方位外层函数(闭包) return inner fn = outer() print('jidj') fn() #fn调用的时机是不确定的,所以inner中用到的东西也需要常驻内存
典型的 超简易爬虫 用到闭包
1 # 非闭包下 2 from urllib.request import urlopen 3 s=urlopen('http://www.xiaohua100.cn/index.html').read() 4 print(s) #非闭包形式下 每次访问都要通过网络 会有时间延迟 5 6 # 闭包下 7 from urllib.request import urlopen 8 def outer(): 9 s = urlopen('http://www.xiaohua100.cn/index.html').read() #将地址作为常驻内存 10 def getcontent(): 11 return s 12 return getcontent 13 print('爬取内容...') 14 pa = outer() # 等于getcontent # 第一次获取地址, 供以后使用 15 print(pa()) #第一次调用有延迟,并将其放入常驻内存中 16 print(pa()) #之后调用很快一瞬间,从常驻内存中获取 17 print(pa()) 18 print(pa())
# 查看是否是闭包
print( 函数名.__closure__ ) 用于查看是否是闭包
1 def func(): 2 def inner(): 3 print('我是inner') 4 print(inner.__closure__) # 不是闭包 5 # None 6 7 def func1(): 8 a=10 9 def inner(): 10 print(a) 11 print(inner.__closure__) # 是闭包 因为inner有访问外层函数中的变量 12 func1() # 返回的是地址 13 #(<cell at 0x0000019A6A959468: int object at 0x0000000059FC6D30>,)
迭代器
特点:
(1) 只能向前, 不能重复
(2) 惰性机制
(3) 节省内存 (体现在生成器中)
1) 使用dir() 来查看该数据包含了那些方法
用来遍历 列表,字符串,元组......可迭代对象
dir() #查看 数据类型有什么方法 print(dir(str)) # dir查看xx类型的数据可以执行哪些方法, __iter__ iterable print(dir(list)) # __iter__ print(dir(int)) # 没有__iter__ # 所有的带__iter__可以使用for循环的, 可迭代对象
2) 可迭代对象可以用__iter__() 来获取迭代器
迭代器里有__next__()
s = "石可心喜欢赵一宁" it = s.__iter__() # 获取迭代器 print(dir(it)) # 迭代器里有__iter__ 还有__next__ 查看迭代器中的方法 结果: ['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__',
'__ge__', '__getattribute__', '__gt__', '__hash__', '__init__',
'__init_subclass__', '__iter__', '__le__', '__length_hint__', '__lt__',
'__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__',
'__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__']
3) 迭代器模拟 for 循环
1 lst = ['春天','夏天','秋天','冬天'] 2 # for el in lst: # 常规的for循环 3 # print(el) 4 it = lst.__iter__() #获取迭代器 5 while 1: 6 try: # 尝试执行 7 el=it.__next__() #获取下一个 8 print(el) 9 except StopIteration: #处理错误 10 break
4) 判断是否为 迭代器 或 迭代对象
Iterable 迭代对象 Iterator 迭代器
1 lst = ['春天','夏天','秋天','冬天'] 2 it = lst.__iter__() #获取迭代器 3 4 # 偏方 5 print("__iter__" in dir(it)) #是否迭代器 True 6 print("__next__" in dir(it)) #是否迭代 True 7 # 可以通过dir来判断数据是否是可迭代的, 以及数据是否是迭代器 8 9 # 官方方案 首先引入模块 10 from collections import Iterable # 可迭代对象 11 from collections import Iterator # 迭代器 12 13 print(isinstance(lst, Iterable)) # True 14 print(isinstance(lst, Iterator)) # False 列表非迭代器 15 print(isinstance(it, Iterable)) # True 16 print(isinstance(it, Iterator)) # True
lst = ["赵四","花生哥, 越来越皮", "天台见"] it = lst.__iter__() # list(参数)把参数进行循环迭代 s = list(it) # 在list中.一定存在for. 一定__next__() print(s) # ["赵四","花生哥, 越来越皮", "天台见"]
装饰器
装饰器就是在不对原来函数做改变的情况下,在它的基础之上封装一些功能
典型示例:计算一个函数运行的时间长短
1、传参的装饰器
import time def show_time(func): def wrapper(a,b): # func中的传参要在内部函数中传参,里面的fun才可以用 start_time=time.time() func(a,b) end_time=time.time() print('spend %s'%(end_time-start_time)) return wrapper @show_time #add=show_time(add) def add(a,b): time.sleep(1) print(a+b) add(2,4)
2、不定长参数的装饰器
import time def waibu(func): def neibu(*args, **kwargs): start = time.time() ret = func(*args, **kwargs) end = time.time() print(end - start) return ret return neibu @waibu def func(*args **kwargs): for i in range(100000000): continue return "OK" print(func()) # 1.7812395095825195 # OK
总结:
1、装饰器还可以用在 Django Flask 中的用户验证登录中,验证身份

浙公网安备 33010602011771号