一、作用域说明(一)

#加载顺序:内置 -- 全局 -- 局部#名字查找顺序:局部 -- 全局 -- 内置#作用域关系:在函数定义时已经固定,与调用位置无关
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

第四(装饰器、迭代器、生成器)相关推荐

  1. python基础二 函数 递归 装饰器 迭代器 生成器 内置函数 二分法应用

    函数 迭代器 生成器 拆包和装包 tup=("j1","a1","c1","k1") a,b,c,d=tup print ...

  2. python的装饰器、迭代器、yield_python装饰器,迭代器,生成器,协程

    python装饰器[1] 首先先明白以下两点 #嵌套函数 defout1():definner1():print(1234) inner1()#当没有加入inner时out()不会打印输出1234,当 ...

  3. python装饰器+迭代器+生成器

    1.函数嵌套:在调用一个函数的过程中,调用了其他函数 def f1():x=1def f2():print('from f2')f2() f1() 2.名称空间与作用域 a. 名称空间:存放名字与变量 ...

  4. Python中的装饰器,迭代器,生成器

    1. 装饰器 装饰器他人的器具,本身可以是任意可调用对象,被装饰者也可以是任意可调用对象. 强调装饰器的原则:1 不修改被装饰对象的源代码 2 不修改被装饰对象的调用方式 装饰器的目标:在遵循1和2的 ...

  5. 函数进阶---闭包/装饰器/迭代器/生成器---高级特性

    待完成... 转载于:https://www.cnblogs.com/py-coder/p/10037232.html

  6. day4 匿名函数、装饰器、生成器、迭代器、内置函数、 json 与 pickle 模块

    文章目录 1.列表生成式 2.匿名函数 3.装饰器 4.生成器 5.迭代器 6.内置函数 7.json & pickle 序列化与反序列化 1.列表生成式 可通过特定语句便捷生成列表 list ...

  7. day11 - 15(装饰器、生成器、迭代器、内置函数、推导式)

    day11:装饰器(装饰器形成.装饰器作用.@语法糖.原则.固定模式) 装饰器形成:最简单的.有返回值的.有一个参数的.万能参数 函数起的作用:装饰器用于在已经完成的函数前后增加功能 语法糖:使代码变 ...

  8. python的装饰器迭代器与生成器_python3 装饰器、列表生成器、迭代器、内置方法详解等(第四周)...

    前言: 为什么要学习python3? 原因: 1.学习一门语言能力 2.通过该语言能力完成测试自动化以及独立完成自测框架知识 那么我要做什么呢? 1.每天花十个小时完成python3的学习 要在什么地 ...

  9. 装饰器,生成器,迭代器

    文章目录 装饰器 什么是装饰器 为什么使用装饰器 装饰器的使用场景 用户认证,判断用户是否登录 计算函数运行时间(算是一个功能,在项目中用的不多) 记录日志 redis缓存 装饰器1----能够适应9 ...

  10. Python基础教程:带参装饰器、生成器、迭代器、for循环迭代器、枚举

    带参装饰器 装饰器为被装饰的函数添加新功能,需要外界参数 outer参数固定一个,就是func inner参数固定和被装饰的参数固定,也不能添加新参数 可以借助函数的嵌套定义,外层给内层传参 def ...

最新文章

  1. webkit内核 css,纯CSS改变webkit内核浏览器的滚动条样式
  2. python多线程处理图片_Python斗图网多线程爬取图片
  3. Memcached与Redis
  4. osg中实现HUDAxis功能
  5. 【Maven学习笔记(二)】Maven的安装与配置
  6. 使用UIActivityIndicatorView 和多线程
  7. 红皮书--SQL语句
  8. wordpress 资料管理系统_说一说库存管理系统。
  9. 月薪30k的PHP架构师的成长路线图1.0!
  10. linux redhat 去掉警报声音
  11. 仙剑四小说【第一章:结伴入世(下)】
  12. Dota2 无法连接至steam网络 【已解决】
  13. 笑话 php 程序员,[每天程序员]笑死人不偿命的程序员段子
  14. 【Chrome扩展程序】解决“只能通过Chrome网上应用商店安装该程序”的方法
  15. 玩转基因组浏览器之IGV展示bam文件
  16. 根号分治 + 入门题目
  17. 将《2020中国统计年鉴》中的GDP数据换算成不变GDP数据
  18. SpringMVC的参数传递
  19. 一个让人类窒息的AI工具,或许未来人工智能真的能代替人类!
  20. 快来跟我一起学 React(Day8)

热门文章

  1. ITA结合测试(总结之六:ITA上的时间,与本地时间)
  2. Spark2.2出现异常:ERROR SparkUI: Failed to bind SparkUI
  3. thinkphp 调用wsdl接口实例化SoapClient抛出异常
  4. 【虚拟机ubuntu设置ssh】ssh连不上问题解决方法
  5. MySQL在并发场景下的问题及解决思路
  6. Connection reset原因分析和解决方案
  7. 什么是mapDispatchToProps?
  8. 如何在JUnit4中按特定顺序运行测试方法?
  9. Android:SQLiteOpenHelper数据库的两套API
  10. 接口报params province error_Python接口测试实践之用例封装及测试报告生成