(六) 装饰器,迭代器,生成器等

本文详细介绍了Python中的装饰器,包括其定义、应用及带参数的装饰器,展示了如何在不修改原函数代码的情况下扩展功能。同时,文章还探讨了列表、集合和字典推导式,以及迭代器的概念和使用。通过实例,解释了生成器的运作机制及其在循环中的应用。此外,还提及了可迭代对象和迭代器在for循环中的作用。

(一) 装饰器

1. 引入
def func(arg):
    def inner():
        arg()
    return inner

def f1():
    print(123)
    return 666

v1 = func(f1)   # inner 其中参数为f1
res = v1()  #执行inner()函数,执行f1()函数,inner函数返回None 
print(res)

'''
123
None
'''
def func(arg):
    def inner():
        return arg()
    return inner

def f1():
    print(123)
    return 666

v1 = func(f1)   # inner 其中参数为f1
res = v1()  #执行inner()函数,执行f1()函数,f1返回666,inner函数返回666
print(res)

'''
123
666
''' 
def func(arg):
    def inner():
        return arg()
    return inner

def index():
    print('123')
    return '666'

# 示例一
v1 = index()   # 执行index函数,打印123,返回666
# 示例二
v2 = func(index)  # 开辟内存空间,v2 =inner (含index)
index = 666
v3 = v2()         #执行inner函数,执行index函数,返回666
# 示例三
v4 = func(index)
index = v4
index()
2. 装饰器的定义

在不改变原函数的内部代码的前提下,可以在函数执行前后做一些操作

def func(arg):
    def inner():
        print('before')
        v = arg()
        print('after')
        return v
    return inner

#第一步:执行func()并将向岸边的函数作为参数进行传递,相当于func(index)
#第二步:将func的返回值重新赋值给下边的函数鸣,index = func(index)
@func
def index():
    print('123')
    return "666"

print(index)
3. 装饰器的应用

应用场景:在给函数扩展功能时应用
应用1

import time

def func1():
    time.sleep(1)
    print('func1')

def func2():
    time.sleep(2)
    print('func2')

def func3():
    time.sleep(3)
    print('func3')

start1_time = time.time()
func1()
end1_time =time.time()
print(end1_time-start1_time)

start2_time = time.time()
func2()
end2_time =time.time()
print(end2_time-start2_time)

start3_time = time.time()
func3()
end3_time =time.time()
print(end3_time-start3_time)


'''
func1
1.0003492832183838
func2
2.0002355575561523
func3
3.0006797313690186
'''
def func(index):
    def inner():
        start_time = time.time()
        index()
        end_time = time.time()
        print(end_time - start_time)
    return inner


@func
def func1():
    time.sleep(1)
    print('func1')
@func
def func2():
    time.sleep(2)
    print('func2')
@func
def func3():
    time.sleep(3)
    print('func3')

func1()
func2()
func3()

应用2

def add_user():
    #1. 判断用户是否已经登陆
    #2.已经登陆可以继续
    pass

def del_user():
    # 1. 判断用户是否已经登陆
    # 2.已经登陆可以继续
    pass

def update_user():
    # 1. 判断用户是否已经登陆
    # 2.已经登陆可以继续
    pass
4. 带参数的装饰器

flask框架+django缓存+写装饰器实现被装饰函数要执行N次

def x(num):
    def wrapper(func):
        def inner(*args,**kwargs):
            res = func(*args,**kwargs)
            return res
        return inner
    return wrapper

#1. 执行v1=wrapper(3)
#2. @v1->index(v1)  =>res = v1(index)
#3. index = res

@x(3)
#等价于 @wrapper 类似于一个闭包,但是传入的参数,可以进行使用
def index():
    pass

注意:在没有调用函数的时候,x(3),wrapper()除inner函数以外就已经被执行了

写一个带参数的装饰器,实现:参数是多少,被装饰的函数就要执行多少次,把每次执行的结果添加到一个列表中,最终返回列表

def calc(num):
    def wrapper(func):
        def inner(*args,**kwargs):
            lst = []
            for i in range(num):
                res = func()
                lst.append(res)
            return lst
        return inner
    return wrapper

@calc(5)
def func():
    print('111')
    return '666'

v1 = func()
print(v1)

若返回最大值,则为

def calc(num):
    def wrapper(func):
        def inner(*args,**kwargs):
            value = 0
            for i in range(num):
                res = func()
                if res > value:
                	value = res
            return value
        return inner
    return wrapper

如果有990个函数是做一些操作,10个函数做其他的操作,则可以如下

def calc(counter):
    def wrapper(func):
        def inner(*args,**kwargs):
            lst = []
            if counter:
                pass
            else:
                pass
            for i in range(counter):
                res = func()
                lst.append(res)
            return lst
        return inner
    return wrapper

@calc(True)
def func990():
    pass


@calc(False)
def func10():
    pass

5. 多个装饰器(欠)

x2装饰func , x1 装饰(x2装饰func的结果)

@x1
@x2
def func():
	pass
6. 装饰器的总结
  1. 目的:在不改变原函数的基础上,在函数执行前后自定义功能
  2. 编写装饰器【记住】
def wrapper(func):
	def inner(*args,**kwargs):
		res = func(*args,**kwargs)
		return res
	return inner
	
@wrapper
def index():
	pass
	
v=index
print(v)
  1. inner函数参数*args,**kwargs的原因:可以方便多个参数个数不一样的函数进行装饰器的调用

(二) 推导式

1. 列表推导式

目的:方便的生成列表
基本格式

v1 = [ i for i in 可迭代对象]
v1 = [ i for i in 可迭代对象 if 条件] #如果满足条件,则i保留在列表中,否则不保留
val = [i for i in 'alex']
print(val)
v1 = [i+100 for i in range(10)]
print(v1)



v1 = []
for i in range(10):
    v1.append(i+100)
print(v1)
v1 = [99 if i >5 else 66 for i in range(10)]
def func():
    pass
v4 = [func for i in range(10)]  #10个func


v5 = [lambda:100 for i in range(10)]  #10个lambda
res = v5[9]()
print(res)

v6 = [lambda:100+i for i in range(10)]  #10个lambda
res = v6[9]()
print(res)


v7 = [i for i in range(10) if i >5]
print(v7)   #6,7,8,9

#面试题【新浪】
v8 = [lambda x :x*i for i in range(10)]
res = v8[0](2)
print(res)


#面试题
def num():
    return [lambda x : i*x for i in range(4)]
# num()  [lambda,lambda,lambda,lambda]
print([m(2) for m in num()])
# i = 3
# [lambda 2,lambda 2,lambda 2,lambda 2]
# [6,6,6,6]
2. 集合推导式

除了括号不一样,其他与列表都一样[ ] --> { }

3. 字典推导式
v1 = ['k'+str(i):i for i in range(10)]
print(v1)

其他与列表一样

(三) 迭代器

1. 迭代器的定义

一般自己是不会写迭代器的,要会用。
迭代器帮助对某种对象中的元素进行逐一获取。

  • 列表转换成迭代器:iter([11,223,33])
v1 = [11,2,3]

#将列表转换成迭代器
v2 = iter(v1)
print(type(v2))

#将迭代器中的第一个元素取出来
res1 = v2.__next__()
print(res1 )
res2 = v2.__next__()
print(res2 )
res3 = v2.__next__()
print(res3 )
res4 = v2.__next__()
print(res4 )


'''
<class 'list_iterator'>
11
2
3
报错:StopIteration,当超过迭代范围就会终止,并报错
'''

列表/元组/集合/字符串/字典 【序列】中的每一个元素读出

v1 = [11,2,3]
v2 = iter(v1)   #等价于v1.__iter__()
while True:
    try:
        print(v2.__next__())
    except Exception as e:
        pass

迭代器的使用步骤

  1. 列表转换成迭代器,res = iter(v1) 或res = v1__iter__()
  2. 迭代器想要获取某些值,反复调用val = v1. __next__()
  3. 直到报错:StopIteration,表示迭代完成
  4. 如何判断一个对象是否是迭代器:看其内部是否有__next__()方法
  5. for循环的内部也在调用迭代器
2. 可迭代对象
  1. 可以被for循环的
  2. 内部有__iter()__方法,且返回一个迭代器

(三) 生成器


def func():
    print(123)
    yield 1
    print(11)
    yield 2
    print(22)

v1 = func()


for item in v1:
    print(item)
  1. 生成器函数,内部含有yield
  2. 函数内部代码不执行,返回一个生成器对象
  3. 生成器可以被for循环,一旦开始循环,那么函数内部代码就会开始执行
  4. 最后⼀个yield执⾏完毕. 再次__next__()程序报错
  5. 生成器的标志:yield
  6. 生成器也是一种特殊的可迭代对象
def func():
    print("111")
    yield 222
    print("333")
    yield 444
gener = func()
ret = gener.__next__()
print(ret)
ret2 = gener.__next__()
print(ret2)
ret3 = gener.__next__()
# 最后⼀个yield执⾏完毕. 再次__next__()程序报错
print(ret3)

为了使生成器在循环过程中停止,可以通过条件return的方式,终止循环。从而程序避免报错。

def func():
    count = 1
    while True:
        yield count
        count +=1
        if count == 100:
            return

v1 = func()
for item in v1:
    print(item)

生成器的标志:yield。不论这个yield函数是否被执行,他都是生成器函数

def func():
    return 1
    yield 1

v1 = func()
print(v1,type(v1))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值