第四(装饰器、迭代器、生成器)
一、作用域说明(一)
#加载顺序:内置 -- 全局 -- 局部#名字查找顺序:局部 -- 全局 -- 内置#作用域关系:在函数定义时已经固定,与调用位置无关 x=1 def f1():def f2():print(x)return f2func=f1() x=999 func() #fun 找的是f1,f1找的是f2,f2打印x,x在局部没有,就找全局的,也就是x=1 #调用阶段,全局的x已经被修改为999,所以打印的是999
二、作用域说明(二)
x=1 def f1():def f2():print(x)return f2def foo(func):x=888func()foo(f1())#foo执行,参数是func,也就是f1,f1找f2,f2找x的值,也就是1,x是全局的,已经固定好了 #foo的时候,局部的x=888的值,不会修改全局的x,所以结果是1
三、闭包函数
#闭包函数 #1.定义在函数内部的函数 #2.包含对外部作用域名字的引用,而不是对全局作用域名字的引用 x=1 def f1():x=893def f2():print(x)return f2func=f1() func()#f2定义在函数内部;对外部作用域x=893引用,而没有引用全局的x,所以f2就是闭包函数
闭包函数进一步说明
#通过闭包思想,给函数传参,如下例子: #想给函数wrapper传入参数,可以封装到另外一个函数里,此时,wrapper就是闭包函数,无论如何都有一个参数x=629 x=730 def deco():x=629def wrapper():print(x)return wrapperfunc=deco() func() #调用的时候,就没必要每次传入参数
四、装饰器前言
#需求:如下函数,计算函数执行时间,但不修改源代码 #第一步: import time def index():time.sleep(3)print("Welcome to the first page")def wrapper(func):start=time.time()func()stop=time.time()print("execute time is %s" %(stop-start))wrapper(index) #这样可以得到结果,但是修改了调用方式,调用方式应该是index()#第二步 #不想给wrapper传参,就需要用闭包思想,将参数放入外部作用域,如下import time def index():time.sleep(3)print("Welcome to the first page")def timmer():func=indexdef wrapper():start=time.time()func()stop=time.time()print("execute time is %s" %(stop-start))return wrapperindex=timmer() #获取wrapper index() #调用wrapper #刚才的需求已经实现#第三步骤,如果再来一个函数 import time def index():time.sleep(3)print("Welcome to the first page")def home():time.sleep(3)print("Welcome to the home page")def timmer():func=indexdef wrapper():start=time.time()func()stop=time.time()print("execute time is %s" %(stop-start))return wrapper#这样,如何实现,对home也可以? import time def index():time.sleep(3)print("Welcome to the first page")def home():time.sleep(3)print("Welcome to the home page")#对timmer函数传参 def timmer(func):#func=index #将此处定义的参数传入def wrapper():start=time.time()func()stop=time.time()print("execute time is %s" %(stop-start))return wrapperindex=timmer(index) home=timmer(home) index() home()
五、装饰器
#对于上面的实现,装饰器的写法如下: import timedef timmer(func):def wrapper():start=time.time()func()stop=time.time()print("execute time is %s" %(stop-start))return wrapper@timmer #index=timmer(index) def index():time.sleep(3)print("Welcome to the first page")@timmer #home=timmer(home) def home():time.sleep(3)print("Welcome to the home page")index() home()
返回结果:
六.装饰器后续(一)
如果home有一个参数的条件?先注释掉index
import timedef timmer(func):def wrapper():start=time.time()func()stop=time.time()print("execute time is %s" %(stop-start))return wrapper# @timmer #index=timmer(index) # def index(): # time.sleep(3) # print("Welcome to the first page") @timmer #home=timmer(home) def home(name): #如果home有一个参数呢time.sleep(3)print("Welcome to the home page %s" %name)# index() home()
报错:
分析:
给home加了参数,home其实就是timmer的的参数,timmer运行,调用的wrapper,wrapper调用的是func,给func传参,也就是wrapper传参
import timedef timmer(func):def wrapper(name): #此处传参start=time.time()func(name) #这里传参stop=time.time()print("execute time is %s" %(stop-start))return wrapper# @timmer #index=timmer(index) # def index(): # time.sleep(3) # print("Welcome to the first page") @timmer #home=timmer(home) def home(name): #如果home有一个参数呢time.sleep(3)print("Welcome to the home page %s" %name)# index() home('ckl')
这样调用成功:
问题来了,如果调用index呢?
import timedef timmer(func):def wrapper(name): #此处传参start=time.time()func(name) #这里传参stop=time.time()print("execute time is %s" %(stop-start))return wrapper@timmer #index=timmer(index) def index():time.sleep(3)print("Welcome to the first page")@timmer #home=timmer(home) def home(name): #如果home有一个参数呢time.sleep(3)print("Welcome to the home page %s" %name)index() home('ckl')
报错:
解决思路,有没有用方法,既可以传参,也可以不传参,可以用*args**kwargs
import timedef timmer(func):def wrapper(*args,**kwargs): #此处传参start=time.time()func(*args,**kwargs) #这里传参stop=time.time()print("execute time is %s" %(stop-start))return wrapper@timmer #index=timmer(index) def index():time.sleep(3)print("Welcome to the first page")@timmer #home=timmer(home) def home(name): #如果home有一个参数呢time.sleep(3)print("Welcome to the home page %s" %name)index() home('ckl')
解决:
eval 用法:
七、无参数装饰器用户认证示例
用户文件db.txt
{'ckl':'123456','zld':'67890'}
认证程序:
#无参装饰器 current_user={'user':None}def auth(func):def wrapper(*args,**kwargs):if current_user['user']:return func(*args,**kwargs)name = input('name: ').strip()password = input('password: ').strip()with open('db.txt',encoding='utf-8') as f:user_dic = eval(f.read())if name in user_dic and password == user_dic[name]:res = func(*args,**kwargs)current_user['user']=namereturn reselse:print('user or password error')return wrapper@auth def index():print('from index')@auth def home(name):print('welcome to home %s' %name)index() home('ckl')
运行结果:
八、带参数装饰器
问题:接上,这样用户认证不是文件,是其它来源呢?如下:
current_user={'user':None}def auth(func):def wrapper(*args,**kwargs):if auth_type == 'file':if current_user['user']:return func(*args,**kwargs)name = input('name: ').strip()password = input('password: ').strip()with open('db.txt',encoding='utf-8') as f:user_dic = eval(f.read())if name in user_dic and password == user_dic[name]:res = func(*args,**kwargs)current_user['user']=namereturn reselse:print('user or password error')elif auth_type == 'mysql':print("from mysql")elif auth_type == 'oracle':print("from mysql")else:print("not found your type")return wrapper@auth def index():print('from index')@auth def home(name):print('welcome to home %s' %name)index() home('ckl')
分析
#那么,auth_type参数传到哪里?
#如果加到这里
def wrapper(*args,**kwargs,auth_type):
#这样就违反了wrapper的定义作用,这里不能加参数
#加到这里呢
def auth(func,auth_type):
#这样就违反了auth的认证,无法加参数
#那么,可以吧参数加到auth上面即可
auth_type='mysql'def auth(func):
#这是解决方法,但是必须再包一层,把参数带入,并通过返回,打破层级限制
带参装饰器 current_user={'user':None}def auth(auth_type='file'):def deco(func):def wrapper(*args, **kwargs):if auth_type == 'file':if current_user['user']:return func(*args, **kwargs)name = input('name: ').strip()password = input('password: ').strip()with open('db.txt', encoding='utf-8') as f:user_dic = eval(f.read())if name in user_dic and password == user_dic[name]:res = func(*args, **kwargs)current_user['user'] = namereturn reselse:print('user or password error')elif auth_type == 'mysql':print("from mysql")elif auth_type == 'oracle':print("from mysql")else:print("not found your type")return wrapper return deco@auth(auth_type='mysql') def index():print('from index')@auth() def home(name):print('welcome to home %s' %name)index() home('ckl')
九、迭代器
可迭代对象iterable:凡是对象下有__iter__方法;对象.__iter__,该对象就是可迭代对象
字典示例说明
dic = {'ckl':123,'zld':'456'}i=dic.__iter__() #dic有__iter__方法,dic就是可迭代对象 #i 就是迭代器iterator #i.__next__() == next(i) print(next(i)) print(next(i)) print(next(i)) #StopIteration
结果:
列表示例说明
s_list = ['hi','new','world'] s = s_list.__iter__() #s_list就是可迭代对象,s是迭代器 print(next(s)) print(next(s)) print(next(s)) print(next(s))
结果:
十、使用迭代器与不使用迭代器对比
列表示例说明
未使用迭代器取值操作,依赖索引
s_list = ['hi','new','world'] count=0 while count < len(s_list):print(s_list[count])count+=1
结果:
使用迭代器取值操作
s_list = ['hi','new','world'] s_i = s_list.__iter__() #得到list的迭代器 while True:try:print(next(s_i)) #从迭代器里取值except StopIteration:break
结果:
字典示例说明
未使用迭代器之前
dic = {'ckl':123,'zld':'456','nbb':789} for i in dic:print(i,dic[i])
运行结果
使用迭代器:
dic = {'ckl':123,'zld':'456','nbb':789} i_dic = iter(dic) # dic.__inter__() while True:try:s=next(i_dic)print(s,dic[s])except StopIteration:break
结果:
十一、迭代器优缺点
迭代器对象:
1.有__iter__,执行仍然是迭代本身
2.有__nex__
迭代器优点
1.提供了一种统一的(不依赖索引的)迭代方式
2.迭代器本身,比起其它数据类型更节省内存
文件示例说明
文件内容:
222 333 333 333 你好啊,世界你好啊,世界 333 zhende 你好啊,世界 .....
文件打开读取的操作:
with open('access.log','r') as f: #f.__iter__() #f就是一个迭代器,拥有__inter__和__next__print(next(f))print(next(f))print(next(f))print(next(f))
结果:
这样操作,更节省内存,不需要一下将所有内容加载到内存,需要一条取一条
迭代器缺点
1.一次性,只能往后走,不能回退,不如索引取值灵活
2.无法预知什么时候取值结束,即无法预知长度
for 循环原理
#for循环打开的都是可迭代对象 s_list = ['hi','new','world','like'] for item in s_list: print(item)
补充:判断可迭代对象与迭代器对象
可迭代对象判断:
from collections import Iterable,Iterators_list = ['hi','new','world','like'] dic = {'ckl':123,'zld':'456','nbb':789} s = 'hello' t = ('a','b','c','d') set1 = {4,5,6,7,8} f1=open('db.txt')print(isinstance(s_list,Iterable)) print(isinstance(s,Iterable)) print(isinstance(t,Iterable)) print(isinstance(set1,Iterable)) print(isinstance(f1,Iterable))
结果:
迭代器判断:
from collections import Iterable,Iterators_list = ['hi','new','world','like'] dic = {'ckl':123,'zld':'456','nbb':789} s = 'hello' t = ('a','b','c','d') set1 = {4,5,6,7,8} f1=open('db.txt')print(isinstance(s_list,Iterator)) print(isinstance(s,Iterator)) print(isinstance(t,Iterator)) print(isinstance(set1,Iterator)) print(isinstance(f1,Iterator))#只有文件是迭代器
结果:
十二、生成器
生成器:在函数内部包含yield关键字,那个该函数执行的结果是生成器
生成器就是一个迭代器
yield的功能:
1.把函数的结果做成迭代器(以一种优雅的方式封装好__iter__,__next__,方法)。
2.yield暂停函数,保存状态
def func():print("Welcome")yield 1 #暂停函数运行,并且有返回值print("The")yield 2print("New")yield 3print("World")g=func() #g.__iter__() g.__next__() g有这两个方法,g就是一个迭代器对象 next(g) next(g) next(g) next(g) #StopIterationfor i in g: #循环迭代器,打印结果print(i)
python3的range函数就是用yield,所以无论存多少值,内存都不会爆。因为只有在调用的时候才存值,且存一个。
模拟range
def my_range(x,y):while True:if x == y: #如果起始值等于结束值,就抛出异常raise StopIterationyield x #暂停并return 起始值x+=1g=my_range(1,4)print(next(g)) print(next(g)) print(next(g)) print(next(g)) #超出范围
结果:
完整如下:
def my_range(x,y):while True:if x == y: #如果起始值等于结束值,就抛出异常raise StopIterationyield x #暂停并return 起始值x+=1g=my_range(1,4)# print(next(g)) # print(next(g)) # print(next(g)) # print(next(g)) #超出范围 for i in g:print(i)
结果:
yield和return区别
相同:都有返回值
不同:return只能返回一次值程序就结束;yield可以返回多次值,暂停函数的运行
模拟tail
实现tail方法,之前实现:
import timedef tailf(f_name):with open(f_name,'r') as fb:fb.seek(0,2) #光标跳到文件末尾while True: #一直循环content=fb.readline()if content: #如果有内容,打印结果print(content)else:time.sleep(0.5) #没有等待0.5秒,再循环 tailf('access.log')
文件内容:
222 333 333 333 你好啊,世界你好啊,世界 333 zhende ....
追加内容脚本:
with open('access.log','a') as fa:fa.writelines("hi girl")
运行tail程序:
运行追加程序
查看结果:
思考:如果我想实现过滤呢,如tailf ckl.txt | grep 'error' 这样的功能呢?
需要将tail的结果传递给grep程序
修改tail方法,增加grep
import timedef tailf(f_name):with open(f_name,'r') as fb:fb.seek(0,2)while True:content=fb.readline()if content:yield content #将结果返回,并且暂停else:time.sleep(0.5)def grep(pattern,lines):for line in lines:if pattern in line:print(line)# tailf('access.log') grep('error',tailf('access.log')) #将tailf的结果追加到grep里
运行结果:
没有任何,打印,因为输出没有过滤条件有error,而结果没有
输出错误字段:
十三、生成器进一步说明
def eater(name):print("%s say: I begin to eat!" %name)while True:food = yieldprint('%s eat %s' %(name,food))tiger_g=eater('tiger') next(tiger_g) print('-------------->') next(tiger_g)
运行结果:
运行分析
- 加载定义的函数eater()
- 加载tiger_g生成器
tiger_g=eater('tiger')
- 调用next方法
next(tiger_g)
- 运行eater(name),参数为tiger
- 运行
print("%s say: I begin to eat!" %name) #打印 tiger say: I begin to eat!
- 进入循环
- 运行如下
food = yield #给food赋值为None,返回None,暂停函数执行
- 运行:
print('-------------->')
- 继续运行next方法
- 进入循环,food的值为None
- 运行:
print('%s eat %s' %(name,food)) #tiger eat None
- 再次进入循环
- food赋值为None,返回值为None,yield结束循环
通过send方法传值:
def eater(name):print("%s say: I begin to eat!" %name)while True:food = yieldprint('%s eat %s' %(name,food))tiger_g=eater('tiger') tiger_g.send('rabbit') print('*'*20) tiger_g.send('bird') print('*'*20)
运行报错:
因为send运行前,迭代对象必须有一个初始值,修改如下:
def eater(name):print("%s say: I begin to eat!" %name)while True:food = yieldprint('%s eat %s' %(name,food))tiger_g=eater('tiger') #第一阶段:初始化 next(tiger_g) #tiger_g.send(None) print('*'*20) #通过send给yield传值 print(tiger_g.send('rabbit')) #给food传值为rabbit,并且返回值为None print('*'*20) print(tiger_g.send('bird')) #给food传值为bird,并且返回值为None print('*'*20)
结果:
现在返回值为空,我可以传入返回值,如下:
def eater(name):print("%s say: I begin to eat!" %name)while True:food = yield 888 #传入返回值print('%s eat %s' %(name,food))tiger_g=eater('tiger') #第一阶段:初始化 next(tiger_g) #tiger_g.send(None) print('*'*20) #通过send给yield传值 print(tiger_g.send('rabbit')) #给food传值为rabbit,并且返回值为None print('*'*20) print(tiger_g.send('bird')) #给food传值为bird,并且返回值为None print('*'*20)
运行结果:
这样,每次的返回值都是888。进一步思考,可否将每次赋值的内容存入到一个列表呢?
修改如下:
def eater(name):food_list = []print("%s say: I begin to eat!" %name)while True:food = yieldfood_list.append(food)print('%s eat %s' %(name,food))print(food_list)tiger_g=eater('tiger') #第一阶段:初始化 next(tiger_g) #tiger_g.send(None) print('*'*20) #通过send给yield传值 print(tiger_g.send('rabbit')) #给food传值为rabbit,并且返回值为None print('*'*20) print(tiger_g.send('bird')) #给food传值为bird,并且返回值为None print('*'*20)
运行结果:
这样,每次传值都追加都列表里,列表的内容就是每次传值的内容,可以将列表的内容返回,如下:
def eater(name):food_list = []print("%s say: I begin to eat!" %name)while True:food = yield food_listfood_list.append(food)print('%s eat %s' %(name,food))print(food_list)tiger_g=eater('tiger') #第一阶段:初始化 next(tiger_g) #tiger_g.send(None) print('*'*20) #通过send给yield传值 print(tiger_g.send('rabbit')) #给food传值为rabbit,并且返回值为None print('*'*20) print(tiger_g.send('bird')) #给food传值为bird,并且返回值为None print('*'*20)
运行结果:
进一步思考
可以将函数的执行结果返回到另外一个函数里,而不结束运行,函数交互运行
def eater(name):food_list = []print("%s say: I begin to eat!" %name)while True:food = yield food_listfood_list.append(food)print('%s eat %s' %(name,food))def feeding():tiger_g = eater('tiger')# 初始化 next(tiger_g)# 给yield传值while True:food = input(">> ").strip()if not food:continuetiger_g.send(food) #传入输入的值 feeding()
运行结果:
每次执行都需要初始化,为初始化添加装饰器
def init(func):def wrapper(*args,**kwargs):g=func(*args,**kwargs)next(g)return greturn wrapper@init def eater(name):food_list = []print("%s say: I begin to eat!" %name)while True:food = yield food_listfood_list.append(food)print('%s eat %s' %(name,food))tiger_g=eater('tiger') tiger_g.send('jimihua')
执行结果,不需要next:
yile 文件内容过滤示例
需求如下:过滤当前架构下所有文件里面包含error字段的文件,并打印出文件名
目录结构如下:
包含error字段的文件为:a1f b2f b3f c2f
实现如下:
#1.获取文件的详细路径 import osdef init(func):def wrapper(*args,**kwargs):g=func(*args,**kwargs)next(g)return greturn wrapper#1.获得文件路径及文件 @init def getpath(target):while True:#获取目录路径filepath = yieldx=os.walk(filepath)#循环所有列表,如果列表最后一个字段为文件则执行for abspath,_,fname in x:if fname:fname=''.join(fname)#将文件文件路径及文件名合并为文件的绝对路径total_file = "%s\%s" %(abspath,fname)#返回文件路径,也就是名的绝对路径fpath=total_file#此处的target就是getfile(),发送文件及文件名 target.send((total_file,fpath))#2.打开文件 @init def getfile(target):while True:#接收文件名和文件路径filename,abspath = yield#打开文件,以读的方式with open(filename,'r') as f_read:#此处的target就是op_file(), 发送打开文件管道及文件路径 target.send((f_read,abspath))# #3.读取文件内容 @init def op_file(target):while True:#接收文打开管道及文件路径f,abspath = yieldfor i in f:#此处的target就是grep(),发送文件行及文件路径 target.send((i,abspath))# #4.过滤错误内容 @init def grep(e_arg):while True:#接收行及文件路径lines,abspath = yield#如果行包含错误字段,就打印此文件路径if e_arg in lines:print(abspath)g=getpath(getfile(op_file(grep('error')))) g.send(r'D:\py_pro\005\lx')
查看结果:
问题:b2f文件出现了两次?分析发现,这个文件里面有两次error的行,解决办法:如果遇到一个error的,后续内容就不再读取
改良如下:
#1.获取文件的详细路径 import osdef init(func):def wrapper(*args,**kwargs):g=func(*args,**kwargs)next(g)return greturn wrapper#1.获得文件路径及文件 @init def getpath(target):while True:#获取目录路径filepath = yieldx=os.walk(filepath)#循环所有列表,如果列表最后一个字段为文件则执行for abspath,_,fname in x:if fname:fname=''.join(fname)#将文件文件路径及文件名合并为文件的绝对路径total_file = "%s\%s" %(abspath,fname)#返回文件路径,也就是名的绝对路径fpath=total_file#此处的target就是getfile(),发送文件及文件名 target.send((total_file,fpath))#2.打开文件 @init def getfile(target):while True:#接收文件名和文件路径filename,abspath = yield#打开文件,以读的方式with open(filename,'r') as f_read:#此处的target就是op_file(), 发送打开文件管道及文件路径 target.send((f_read,abspath))# #3.读取文件内容 @init def op_file(target):while True:#接收文打开管道及文件路径f,abspath = yieldfor i in f:#此处的target就是grep(),发送文件行及文件路径res=target.send((i,abspath)) #------------> 获取到grep()返回的结果if res: #----------------> 如果res为ture就结束循环,不再循环后面的内容break# #4.过滤错误内容 @init def grep(e_arg):tag = False #---------> 起始值为Falsewhile True:#接收行及文件路径lines,abspath = yield tag #------------> 返回tag#如果行包含错误字段,就修改tag为True并打印此文件路径,否则修改为Falseif e_arg in lines:tag = True print(abspath)else:tag = Falseg=getpath(getfile(op_file(grep('error')))) g.send(r'D:\py_pro\005\lx')
执行结果:
十四、递归
递归调用:在调用一个函数的过程中,直接或间接调用了函数本身
def count_age(n):if n == 1:return 20return count_age(n-1)+3print(count_age(5))
结果为:30
分析:
count_age(5) --> count_age(4)+3 --> count_age(3)+3 --> count_age(2)+3 --> count_age(1)+3 #递推 32 <----- 29 + 3 <---------- 26 + 3 <------------ 23 +3 <----------- 20 + 3 #回溯
递归的两个节点:递推,回溯
递归特点:
1.有一个明确的结束条件
2.每次递归规模比上次递归都减小
3.递归效率不高
递归使用的条件:循环的次数无法确定
递归举例:
打印列表的所有元素:
l = [1,2,[3,[4,5,6,[7,8,[9,10,[11,12,13,[14,15,[16,17,18,19,[20,21,22,[23]]]]]]]]]]def func(x):for i in x:if type(i) is not list: #这就是结束条件print(i)else:func(i) func(l)
十五、二分法查找
自己实现的最简单的二分法查找
l = [1,3,4,7,9,12,19,21,26,31,32,39,42,51,58,69,78,93,109]def binary_search(l,num):if len(l) > 1:mid_index = len(l) // 2print(l)if num == l[mid_index]:print("find it")returnelif num > l[mid_index]:l=l[mid_index:]elif num < l[mid_index]:l=l[:mid_index]binary_search(l,num)else:print("not found")binary_search(l,41)
斐波那契数列
1 #!/usr/bin/env python 2 #-*- coding:utf-8 -*- 3 4 def Fobinaq(arg1,arg2,stop): 5 if arg1 == 0: 6 print(arg1,arg2) 7 arg3 = arg1 + arg2 8 print(arg3) 9 if arg3 < stop: 10 Fobinaq(arg2,arg3,stop) 11 12 Fobinaq(0,1,50)
列表旋转90度脚本
[1][2][3][4]
[1][2][3][4]
[1][2][3][4]
[1][2][3][4]
脚本:
1 #!/usr/bin/env python 2 #-*- coding:utf-8 -*- 3 """ 4 列表旋转90度 5 """ 6 7 """ 8 data = [[i for i in range(4)] for m in range(4)] 9 10 for r_index,row in enumerate(data): 11 for c_index in range(r_index,len(row)): 12 tmp = data[c_index][r_index] 13 data[c_index][r_index] = row[c_index] 14 data[r_index][c_index] = tmp 15 16 print('-'*10) 17 for r in data: 18 print(r) 19 """ 20 21 data = [[col for col in range(4)] for row in range(4)] 22 23 for i in range(len(data)): 24 a = [data[i][i] for row in range(4)] 25 print(a)
转载于:https://www.cnblogs.com/ckl893/p/6698976.html
第四(装饰器、迭代器、生成器)相关推荐
- python基础二 函数 递归 装饰器 迭代器 生成器 内置函数 二分法应用
函数 迭代器 生成器 拆包和装包 tup=("j1","a1","c1","k1") a,b,c,d=tup print ...
- python的装饰器、迭代器、yield_python装饰器,迭代器,生成器,协程
python装饰器[1] 首先先明白以下两点 #嵌套函数 defout1():definner1():print(1234) inner1()#当没有加入inner时out()不会打印输出1234,当 ...
- python装饰器+迭代器+生成器
1.函数嵌套:在调用一个函数的过程中,调用了其他函数 def f1():x=1def f2():print('from f2')f2() f1() 2.名称空间与作用域 a. 名称空间:存放名字与变量 ...
- Python中的装饰器,迭代器,生成器
1. 装饰器 装饰器他人的器具,本身可以是任意可调用对象,被装饰者也可以是任意可调用对象. 强调装饰器的原则:1 不修改被装饰对象的源代码 2 不修改被装饰对象的调用方式 装饰器的目标:在遵循1和2的 ...
- 函数进阶---闭包/装饰器/迭代器/生成器---高级特性
待完成... 转载于:https://www.cnblogs.com/py-coder/p/10037232.html
- day4 匿名函数、装饰器、生成器、迭代器、内置函数、 json 与 pickle 模块
文章目录 1.列表生成式 2.匿名函数 3.装饰器 4.生成器 5.迭代器 6.内置函数 7.json & pickle 序列化与反序列化 1.列表生成式 可通过特定语句便捷生成列表 list ...
- day11 - 15(装饰器、生成器、迭代器、内置函数、推导式)
day11:装饰器(装饰器形成.装饰器作用.@语法糖.原则.固定模式) 装饰器形成:最简单的.有返回值的.有一个参数的.万能参数 函数起的作用:装饰器用于在已经完成的函数前后增加功能 语法糖:使代码变 ...
- python的装饰器迭代器与生成器_python3 装饰器、列表生成器、迭代器、内置方法详解等(第四周)...
前言: 为什么要学习python3? 原因: 1.学习一门语言能力 2.通过该语言能力完成测试自动化以及独立完成自测框架知识 那么我要做什么呢? 1.每天花十个小时完成python3的学习 要在什么地 ...
- 装饰器,生成器,迭代器
文章目录 装饰器 什么是装饰器 为什么使用装饰器 装饰器的使用场景 用户认证,判断用户是否登录 计算函数运行时间(算是一个功能,在项目中用的不多) 记录日志 redis缓存 装饰器1----能够适应9 ...
- Python基础教程:带参装饰器、生成器、迭代器、for循环迭代器、枚举
带参装饰器 装饰器为被装饰的函数添加新功能,需要外界参数 outer参数固定一个,就是func inner参数固定和被装饰的参数固定,也不能添加新参数 可以借助函数的嵌套定义,外层给内层传参 def ...
最新文章
- webkit内核 css,纯CSS改变webkit内核浏览器的滚动条样式
- python多线程处理图片_Python斗图网多线程爬取图片
- Memcached与Redis
- osg中实现HUDAxis功能
- 【Maven学习笔记(二)】Maven的安装与配置
- 使用UIActivityIndicatorView 和多线程
- 红皮书--SQL语句
- wordpress 资料管理系统_说一说库存管理系统。
- 月薪30k的PHP架构师的成长路线图1.0!
- linux redhat 去掉警报声音
- 仙剑四小说【第一章:结伴入世(下)】
- Dota2 无法连接至steam网络 【已解决】
- 笑话 php 程序员,[每天程序员]笑死人不偿命的程序员段子
- 【Chrome扩展程序】解决“只能通过Chrome网上应用商店安装该程序”的方法
- 玩转基因组浏览器之IGV展示bam文件
- 根号分治 + 入门题目
- 将《2020中国统计年鉴》中的GDP数据换算成不变GDP数据
- SpringMVC的参数传递
- 一个让人类窒息的AI工具,或许未来人工智能真的能代替人类!
- 快来跟我一起学 React(Day8)
热门文章
- ITA结合测试(总结之六:ITA上的时间,与本地时间)
- Spark2.2出现异常:ERROR SparkUI: Failed to bind SparkUI
- thinkphp 调用wsdl接口实例化SoapClient抛出异常
- 【虚拟机ubuntu设置ssh】ssh连不上问题解决方法
- MySQL在并发场景下的问题及解决思路
- Connection reset原因分析和解决方案
- 什么是mapDispatchToProps?
- 如何在JUnit4中按特定顺序运行测试方法?
- Android:SQLiteOpenHelper数据库的两套API
- 接口报params province error_Python接口测试实践之用例封装及测试报告生成