Python基础5-装饰器与推导式

1.装饰器

  • 1.1 引入装饰器的代码
v = 1
v = 2
def func():
    pass
v = 10
v = fun # 变量v指向了函数func

def base():
    print(1)
def bar():
    print(2)
bar = base
bar()

def func():
    def inner():
        pass
    return inner
v = func()
print(v) # inner函数 <function func.<locals>.inner at 0x11fa53b00>

def func(arg):
    def inner():
        print(arg)
    return inner
v1 = func(1)
v2 = func(2)
print(v1, v2) # <function func.<locals>.inner at 0x11fa507c0> <function func.<locals>.inner at 0x11fa50860>

def func(arg):
    def inner():
        arg()
    return inner
def f1():
    print(123)
v1 = func(f1)
v1()

def func(arg):
    def inner():
        arg()
    return inner
def f1():
    print(123)
    return 666
v1 = func(f1)
result = v1() # 执行inner函数 f1含函数 ---> 123
print(result) # None

def func(arg):
    def inner():
        return arg() # v = arg() return v
    return inner
def f1():
    print(123)
    return 666
v1 = func(f1)
result = v1() # 执行inner函数 f1含函数 ---> 123
print(result) # 666

def func():
    print(1)
v1 = func
func = 666
v1()
print(func)
  • 1.2 装饰器代码
def func(arg):
    def inner():
        print('Before')
        v = arg()
        print('After')
        return v
    return inner
def index():
    print('123')
    return '666'

# 示例1
v1 = index() # 执行index函数,打印123并返回666赋值给v1
print(v1)
# 示例2
v2 = func(index) # v2是inner函数,arg即index函数
index = 666
v3 = v2()
print(v3)
# 示例3
v4 = func(index)
index = v4 # index指向了inner函数
index()
# 示例4
index = func(index)
index()
###################################################
def func(arg):
    def inner():
        v = arg()
        return v
    return inner

# 第1步:执行func函数并将下面的函数名当做参数传递,相当于:func(index)
# 第2步:将func的返回值重新赋值给下面的函数名,相当于:index = func(index)
@func
def index():
    print(123)
    return 666

print(index) # <function func.<locals>.inner at 0x11feb2c00>
  • 1.3 一个和装饰器有关的案例——计算函数执行时间
    • 不用装饰器编写,代码冗余度较高
    import time
    def func1():
        time.sleep(2)
        print(123)
    
    def func2():
        time.sleep(1)
        print(123)
    
    def func3():
        time.sleep(1.5)
        print(123)
    
    start_time1 = time.time() # 获取当前时间
    func1()
    end_time1 = time.time() # 获取当前时间
    print(end_time1-start_time1)
    
    start_time2 = time.time() # 获取当前时间
    func2()
    end_time2 = time.time() # 获取当前时间
    print(end_time2-start_time2)
    
    start_time3 = time.time() # 获取当前时间
    func3()
    end_time3 = time.time() # 获取当前时间
    print(end_time3-start_time3)
    
    • 用装饰器编写:代码重用
      • 在不改变原函数内部代码的基础上,在函数执行之前和之后自动执行某个功能
    # 应用:计算函数执行时间
    import time
    def wrapper(func):
        def inner():
            start_time = time.time()
            v = func()
            end_time = time.time()
            print(end_time-start_time)
            return v
        return inner
    
    @wrapper
    def func1():
        time.sleep(2)
        print(123)
    
    @wrapper
    def func2():
        time.sleep(1)
        print(123)
    
    @wrapper
    def func3():
        time.sleep(1.5)
        print(123)
    
    func1()
    
    ###################################################
    def x(func):
        def y():
            pass # 执行func函数前要做的事情
            ret = func()
            pass # 执行func函数后要做的事情
            return ret
        return y
    
    # 装饰器的应用
    @x
    def index():
        return 10
    
    @x
    def manage():
        pass
    
    # 执行函数,自动触发装饰器了
    v = index()
    print(v)
    
  • 1.4 装饰器编写格式
def outer_func(param):
    def inner_func(*args, **kwargs):
        return param(*args, **kwargs)
    return inner_func
# 问题:为什么要加*args **kwargs
@outer_func
def index():
    pass
index()


def wrapper(func):
    def inner(*args, **kwargs):
        return func(*args, **kwargs)
    return inner

@wrapper
def index():
    print(1123)
index() # 无参数传递

@wrapper
def show(a1):
    print(a1+100)

show(1) # 有参数传递
# index和show传递给装饰函数的参数func,在inner内部index和show会被调用,虽然两个函数被同一个装饰器装饰,但参数个数不一定一致,所以要加可变参数
# 被装饰的函数index show可能不接收参数,也可能接收1个或多个参数,它们最后都会指向inner函数,所以inner要带可变参数

2.列表推导式

  • 2.1 使用目的
    • 简化代码
    • 方便生成一个列表
  • 2.2 格式
v1 = [i for i in 可迭代对象]
v2 = [i for i in 可迭代对象 if 条件 ] # 条件为True才进行append
  • 2.3 案例
v1 = [i for i in 'alex']
v2 = [i + 100 for i in range(10)]
v3 = [99 if i>5 else 66 for i in range(10)]
print(v1, v2, v3)

def func():
    return 100
v4 = [func for i in range(10)]
print(v4) # [<function func at 0x12e9d84a0>, <function func at 0x12e9d84a0>, <function func at 0x12e9d84a0>, <function func at 0x12e9d84a0>, <function func at 0x12e9d84a0>, <function func at 0x12e9d84a0>, <function func at 0x12e9d84a0>, <function func at 0x12e9d84a0>, <function func at 0x12e9d84a0>, <function func at 0x12e9d84a0>]

v5 = [lambda: 100 for i in range(10)]
result = v5[9]()
print(result)
def func():
    return i
v6 = [func for i in range(10)]
result = v6[5]()
print(result)

v7 = [lambda:i for i in range(10)]
result = v7[5]()
print(result)

v8 = [lambda x:x*i for i in range(10)] # 新浪微博面试题
# 1.请问 v8 是什么? ---> 8个匿名函数
# 2.请问v8[0](2)的结果是什么? 执行匿名函数 2*9
print(v8)
print(v8[0](2))

def num():
    return [lambda x:i*x for i in range(4)]
# num()执行后返回了一个列表,列表元素是4个匿名函数,4个函数的内容一样
print([m(2) for m in num()])

3.集合推导式

v1 = {i for i in 'alexxe'}
print(v1)

4.字典推导式

v2 = {'K'+str(i):i for i in range(10)}
print(v2)
posted @ 2025-01-22 15:02  pycoder_666  阅读(27)  评论(0)    收藏  举报