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

news/2025/1/22 15:06:12/文章来源:https://www.cnblogs.com/zjl-linux/p/18685783

1.装饰器

  • 1.1 引入装饰器的代码
v = 1
v = 2
def func():pass
v = 10
v = fun # 变量v指向了函数funcdef base():print(1)
def bar():print(2)
bar = base
bar()def func():def inner():passreturn 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) # Nonedef func(arg):def inner():return arg() # v = arg() return vreturn inner
def f1():print(123)return 666
v1 = func(f1)
result = v1() # 执行inner函数 f1含函数 ---> 123
print(result) # 666def func():print(1)
v1 = func
func = 666
v1()
print(func)
  • 1.2 装饰器代码
def func(arg):def inner():print('Before')v = arg()print('After')return vreturn 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 vreturn inner# 第1步:执行func函数并将下面的函数名当做参数传递,相当于:func(index)
# 第2步:将func的返回值重新赋值给下面的函数名,相当于:index = func(index)
@func
def index():print(123)return 666print(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 vreturn 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 retreturn 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)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/873259.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

米尔瑞芯微第二代8nm高性能AIOT平台-RK3576开发板怎么样?

文章来源公众号:电子开发学习 瑞芯微近期推出了第二代8nm高性能AIOT平台——RK3576。 RK3576应用方向指向工业控制及网关,云终端,人脸识别设备,车载中控,商显等等。参数方面,内置了四核Cortex-A72+四核Cortex-A53,频率最高2.2GHz,内置ARM G52 MC3 GPU,NPU算力高达6TO…

openssl头文件出现DEPRECATEDIN_1_1_0导致引入头文件时程序无法编译

openssl头文件出现DEPRECATEDIN_1_1_0导致引入头文件时程序无法编译我使用的是unbuntu20.04版本中,通过apt安装的openssl,发现openssl中的多个库文件中会出现类似DEPRECATEDIN_1_1_0(unsigned char *ASN1_STRING_data(ASN1_STRING *x)),导致引入头文件时无法编译成功. 例如bio.…

人工智能创新型教师培育计划(第一期)

Skip to contentOpenHydraSearchKMain Navigation首页 课程新一代人工智能经典实验【中学】 XEdu系列【中学】 中小学AI开源课程倡议使用指南活动获取支持On this page人工智能创新型教师培育计划(第一期) 一、组织单位 二、活动背景 三、活动内容 四、活动安排 五、师资介绍…

前置数学

一些必要 trick推式子,先提 \(\sum\) 和 \(\Pi\) 到最前面,然后从后往前合并,必要时考虑更改 \(\sum\) 的取值 看到次方变为斯特林数,\(x^n=\sum\limits_{i=0}^{n} {n \brace i}{x \choose i}i!=\sum\limits_{i=0}^{n}\sum\limits_{i=1}^m{(-1)^{m-i}\frac{i^n}{(m-i)!}}{x…

MUX-VLAN

MUX VLAN(Multiplex VLAN)是一种高级的VLAN技术,它通过在交换机上实现二层流量隔离和灵活的网络资源控制,提供了一种更为细致的网络管理方式。 一、基本概念 MUX VLAN分为主VLAN(Principal VLAN)和多个子VLAN(Subordinate VLAN)。 主VLAN是MUX VLAN配置中的核心VLAN,它…

OpenWrt 挂载 SMB

通过OpenWrt挂载smb存储,并再通过smb分享(实现分布分享统一入口?)添加用户 依赖 opkg install shadow-common opkg install shadow-useradd添加 smb 专用用户 useradd YOUR_SMB_USER_NAME将用户与 smb 服务关联 smbpasswd -a YOUR_SMB_USER_NAMEOpenWrt 设置 挂载 SMB 网络共…

高效批量工作流导入及脚本上线,利用DolphinScheduler接口轻松实现

实现了批量生成DolphinScheduler的任务,当导入时发现只能逐个导入,因此通过接口实现会更方便。 DolphinScheduler接口文档 DolphinScheduler是有接口文档的,地址是 http://IP:12345/dolphinscheduler/swagger-ui/index.html?language=zh_CN&lang=cn不过这文档写的比较简…

IDEA如何打开每日提示?

前言 大家好,我是小徐啊。我们在使用IDEA开发Java应用的时候,经常需要使用IDEA的各种各样的技巧,提示。这个在每次IDEA打开的时候,会自动弹出来。但有时候,我们可能不小心把这个提示设置成关闭了,导致后面打开IDEA的时候,再也不弹出这个提示了。这样我们可能就不能很全面…

如何用vscode打开obj、glb文件,查看3D文件

方案1:安装插件 3D Viewer for VSCode,安装完可以查看obj 但是不懂为啥是白色的 glTF Tools,安装完可以查看gltf 启动位置在右上角:白色小山的图标 这个效果不错,看起来比较舒服。 但是gltf从哪里来呢? 首先我们有一个glb文件,右键它,点击倒数第二行的“glTF: import …

时间序列平稳性的双重假设检验:KPSS与ADF方法比较研究

在进行时间序列分析之前,确定序列的平稳性是一个关键步骤。平稳性指的是时间序列的统计特性(如均值和方差)在时间维度上保持不变。本文将详细介绍如何运用 KPSS 检验和 Dickey-Fuller 检验来验证序列的平稳性。这两种检验方法基于不同的统计假设:KPSS 检验的原假设是数据非…

Svelte 最新中文文档翻译(4)—— 符文(Runes)下

前言 Svelte,一个非常“有趣”、用起来“很爽”的前端框架。从 Svelte 诞生之初,就备受开发者的喜爱,根据统计,从 2019 年到 2024 年,连续 6 年一直是开发者最感兴趣的前端框架 No.1:Svelte 以其独特的编译时优化机制著称,具有轻量级、高性能、易上手等特性,非常适合构…

固定测斜探头 土体位移变化数据支持 助力工程监测 无线传输

固定测斜探头 土体位移变化数据支持 助力工程监测 无线传输FI系列固定测斜探头是一款专为土体内部位移变化监测而设计的高精度测量仪器。无论是深基坑开挖、地铁地基、公路地基、挡土墙、坝体、尾矿库还是山体滑坡等工程项目,我们的测斜探头都能提供准确可靠的数据支持。该测斜…