Python一分钟:装饰器
一、装饰器基础
函数即对象
在python中函数可以作为参数传递,和任何其它对象一样如:str、int、float、list等等
def say_hello(name):return f"Hello {name}"def be_awesome(name):return f"Yo {name}, together we're the awesomest!"def greet_bob(greeter_func):return greeter_func("Bob")
内部函数
在函数内部可以创建函数,这样的函数被称为内部函数:
def parent():print("Printing from parent()")def first_child():print("Printing from first_child()")def second_child():print("Printing from second_child()")second_child()first_child()
在python在交互式shell中运行:
python -i test.py
在使用 Python 时,尤其是在交互式 shell 中,其强大的自省(introspection)能力提供了极大的便利。自省是指对象在运行时能够了解自身属性的能力。
>>> parent()
内部函数只有在父函数被调用时才会被定义,它的作用域仅限于父函数parent()
内:
>>> first_child()
Traceback (most recent call last):...
NameError: name 'first_child' is not defined
函数作为返回值
函数可以作为返回值返回:
def parent(num):def first_child():return "Hi, I'm Elias"def second_child():return "Call me Ester"if num == 1:return first_childelse:return second_child
通过变量保存返回的函数引用,可以像普通函数那样正常调用:
>>> first = parent(1)
>>> second = parent(2)>>> first
<function parent.<locals>.first_child at 0x7f599f1e2e18>>>> second
<function parent.<locals>.second_child at 0x7f599dad5268>
简单的装饰器
def decorator(func):def wrapper():print("Something is happening before the function is called.")func()print("Something is happening after the function is called.")return wrapperdef say_whee():print("Whee!")say_whee = decorator(say_whee)
在shell中运行:
>>> from hello_decorator import say_whee>>> say_whee()
# <function decorator.<locals>.wrapper at 0x7f3c5dfd42f0>
通过@符号来使用装饰器:
def decorator(func):def wrapper():print("Something is happening before the function is called.")func()print("Something is happening after the function is called.")return wrapper@decorator
def say_whee():print("Whee!")
传递参数:
def do_twice(func):def wrapper_do_twice(*args, **kwargs):func(*args, **kwargs)func(*args, **kwargs)return wrapper_do_twice
在shell中运行:
>>> from decorators import do_twice>>> @do_twice
... def return_greeting(name):
... print("Creating greeting")
... return f"Hi {name}"
...>>> return_greeting("Adam")
# Creating greeting
# Creating greeting
# 'Hi Adam'
保留原始信息
当函数被我们之前创建的装饰器装饰时,它的内部信息就会变得混乱,使用@functools.wraps
装饰器可以解决这个问题:
import functoolsdef do_twice(func):@functools.wraps(func)def wrapper_do_twice(*args, **kwargs):func(*args, **kwargs)return func(*args, **kwargs)return wrapper_do_twice
在shell中运行:
>>> from decorators import do_twice>>> @do_twice
... def say_whee():
... print("Whee!")
...>>> say_whee
<function say_whee at 0x7ff79a60f2f0>>>> say_whee.__name__
'say_whee'>>> help(say_whee)
Help on function say_whee in module whee:say_whee()
可以看到经过@functools.wraps
装饰器后,say_whee
函数的元数据被保留下来,包括函数名、文档字符串等。
二、更复杂的装饰器
嵌套装饰器
装饰器可以堆叠用于一个函数:
>>> from decorators import debug, do_twice>>> @debug
... @do_twice
... def greet(name):
... print(f"Hello {name}")
带参数的装饰器
我们可以定义能够接收参数的装饰器,如下:
from decorators import repeat@repeat(num_times=4)
def greet(name):print(f"Hello {name}")greet("World")
实现方法如下:
import functools# ...def repeat(num_times):def decorator_repeat(func):@functools.wraps(func)def wrapper_repeat(*args, **kwargs):for _ in range(num_times):value = func(*args, **kwargs)return valuereturn wrapper_repeatreturn decorator_repeat
拆分讲解上面的代码:
首先decorator_repeat
部分的行为,就和我们之前定义的普通装饰器一样:
...def decorator_repeat(func):@functools.wraps(func)def wrapper_repeat(*args, **kwargs):for _ in range(num_times):value = func(*args, **kwargs)return valuereturn wrapper_repeat
...
外层由repeat()
函数接收参数,并返回wrapper_repeat
装饰器的引用。
在装饰器中跟踪状态
可以实现装饰器对象中添加属性来追踪函数调用次数:
import functoolsdef count(func):@functools.wraps(func)def warp(*args, **kwargs):warp.num_calls += 1print(f"Call {warp.num_calls} of {func.__name__}()")return func(*args, **kwargs)warp.num_calls = 0return warp@count
def hello():print("Hello")hello()
hello()
hello()
类装饰器
有两种不同的方式可以在类中使用装饰器,第一种方法和我们上面学到的在函数中使用装饰器的方法非常类似。
Python有很多内置的装饰器很常用:
@classmethod
@staticmethod
@property
在python中维护状态的典型方法就是使用类。之前实现的count
函数可以使用类装饰器重写。为了使实例可调用,需要实现.__call__()
方法:
>>> class Counter:
... def __init__(self, start=0):
... self.count = start
... def __call__(self):
... self.count += 1
... print(f"Current count is {self.count}")
每次调用实例都会执行.__call__()
方法:
>>> counter = Counter()
>>> counter()
Current count is 1>>> counter()
Current count is 2>>> counter.count
实现装饰器类的典型方法是应该实现.__init__()
和.__call__()
import functools# ...class CountCalls:def __init__(self, func):functools.update_wrapper(self, func)self.func = funcself.num_calls = 0def __call__(self, *args, **kwargs):self.num_calls += 1print(f"Call {self.num_calls} of {self.func.__name__}()")return self.func(*args, **kwargs)
使用方法:
>>> from decorators import CountCalls>>> @CountCalls
... def say_whee():
... print("Whee!")
...>>> say_whee()
# Call 1 of say_whee()
# Whee!>>> say_whee()
# Call 2 of say_whee()
# Whee!>>> say_whee.num_calls
# 2
原文链接
相关文章:
Python一分钟:装饰器
一、装饰器基础 函数即对象 在python中函数可以作为参数传递,和任何其它对象一样如:str、int、float、list等等 def say_hello(name):return f"Hello {name}"def be_awesome(name):return f"Yo {name}, together were the awesomest!"def gr…...

Docker部署ddns-go教程(包含完整的配置过程)
本章教程教程,主要介绍如何用Docker部署ddns-go。 一、拉取容器 docker pull jeessy/ddns-go:v6.7.0二、运行容器 docker run -d \--name ddns-go \--restart unless-stopped \...

简单多状态dp第三弹 leetcode -买卖股票的最佳时机问题
309. 买卖股票的最佳时机含冷冻期 买卖股票的最佳时机含冷冻期 分析: 使用动态规划解决 状态表示: 由于有「买入」「可交易」「冷冻期」三个状态,因此我们可以选择用三个数组,其中: ▪ dp[i][0] 表示:第 i 天结束后,…...

游戏化在电子课程中的作用:提高参与度和学习成果
游戏化,即游戏设计元素在非游戏环境中的应用,已成为电子学习领域的强大工具。通过将积分、徽章、排行榜和挑战等游戏机制整合到教育内容中,电子课程可以变得更具吸引力、激励性和有效性。以下是游戏化如何在转变电子学习中发挥重要作用&#…...

php+mysql安装
1.卸载mysql 没启动不停止 2.下载 3.解压 4.点击安装 5.出现成功 端口占用修改 修改端口89或者87 可视化扩展 修改后重启 开启扩展...

音视频入门基础:FLV专题(5)——FFmpeg源码中,判断某文件是否为FLV文件的实现
一、引言 通过FFmpeg命令: ./ffmpeg -i XXX.flv 可以判断出某个文件是否为FLV文件: 所以FFmpeg是怎样判断出某个文件是否为FLV文件呢?它内部其实是通过flv_probe函数来判断的。从《FFmpeg源码:av_probe_input_format3函数和AVI…...

Tomcat 乱码问题彻底解决
1. 终端乱码问题 找到 tomcat 安装目录下的 conf ---> logging.properties .修改ConsoleHandler.endcoding GBK (如果在idea中设置了UTF-8字符集,这里就不需要修改) 2. CMD命令窗口设置编码 参考:WIN10的cmd查看编码方式&am…...
RGB颜色模型
RGB颜色模型是一种广泛应用于数字图像和计算机图形领域的颜色表示方法 一、基本概念 RGB 代表红色(Red)、绿色(Green)和蓝色(Blue)三种基本颜色。这些颜色被视为加色模型中的原色,意味着它们可…...
智能工厂的软件设计 创新型原始制造商(“创新工厂“)的Creator原型(统一行为理论)之2
Q8、今天我们继续昨天开始的 “智能工厂的软件设计”以“统一行为理论”为指导原则的 创新型原始制造商的Creator伪代码--创新工厂“原型”。这是在前述将“程序program”问题的三个体现“方面”(逻辑/语言/数学) 视为符号学的三分支(语用语义…...

【个人博客hexo版】hexo安装时会出现的一些问题
项目场景: 项目场景:在完成了GitHub仓库和git的连接之后,就要新建一个文件夹(例如hexo blog)进行下一步hexo的使用 问题描述 例如:如图所示 原因分析: 这些error不用看它到底是什么…...

道路裂缝,坑洼,病害数据集-包括无人机视角,摩托车视角,车辆视角覆盖道路
道路裂缝,坑洼,病害数据集 包括无人机视角,摩托车视角,车辆视角 覆盖道路所有问题 一共有八类16000张 1到7依次为: [横向裂缝, 纵向裂缝, 块状裂缝, 龟裂, 坑槽, 修补网状裂缝, 修补裂缝, 修补坑槽] 道路病害(如裂缝、…...
java接口文档配置
接口文档配置 一. swagger与knife4j 配置 1. 导入依赖 <!--swagger接口文档说明--> <dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId> </dependency> <dependency><groupId>…...

【服务器第二期】mobaxterm软件下载及连接
【服务器第二期】mobaxterm软件下载及连接 前言什么是SSH什么是FTP/SFTP mobaxterm软件介绍mobaxterm软件下载SSH登录使用方法1-新建ssh连接方法2-打开已有的ssh连接方法3-通过ssh命令建立连接 SFTP数据传输方法1-建立ssh连接后直接拖拽方法2-建立sftp连接再拖拽方法3-直接使用…...

排序-----计数排序(非比较排序)
原理: 存在的问题:数组空间浪费 所以要相对映射,不要绝对映射 calloc()函数的功能是:为num个大小为size的元素开辟一块空间,并且把空间的每个字节初始化为0. // 时间复杂度:O(Nrange) // 只适合整数/适合范围集中 // 空间范围度:…...

[Python]案例驱动最佳入门:Python数据可视化在气候研究中的应用
在全球气候问题日益受到关注的今天,气温变化成为了科学家、政府、公众讨论的热门话题。然而,全球气温究竟是如何变化的?我们能通过数据洞察到哪些趋势?本文将通过真实模拟的气温数据,结合Python数据分析和可视化技术&a…...

PyQt5 导入ui文件报错 AttributeError: type object ‘Qt‘ has no attribute
问题描述: 利用 PyQt5 编写可视化界面是较为普遍的做法,但是使用全新UI版本的 Pycharm 修改之前正常的UI文件时,在没有动其他代码的情况下发现出现以下报错 AttributeError: type object Qt has no attribute Qt::ContextMenuPolicy::Defaul…...

Unity中Rigidbody 刚体组件和Rigidbody类是什么?
Rigidbody 刚体组件 Rigidbody 是 Unity 中的一个组件,它可以让你的游戏对象像真实世界中的物体一样移动和碰撞。想象一下,你有一个小球,你希望它像真实世界中的球一样滚动、弹跳和碰撞,那么你就可以给这个小球添加一个 Rigidbod…...

MySQL学习笔记(持续更新中)
1、Mysql概述 1.1 数据库相关概念 三个概念:数据库、数据库管理系统、SQL 名称全称简称数据库存储数据的仓库,数据是有组织的进行存储DataBase(DB)数据库管理系统操纵和管理数据库的大型软件DataBase Mangement System…...
sqlserver插入数据删除数据
1、插入数据 1.1 直接插入 1.1.1 方式一 insert into test values(001,黎明,1),(002,冯绍峰,1),(003,菲菲,2);1.1.2 方式二 insert into test(ID,Name,Sex) values(004,丽丽,2),(005,凌晨,2),(006,虾米,1);1.2 插入部分行 insert into test(ID,Name) values(007,红)2、删除…...
[51单片机] 简单介绍 (一)
文章目录 1.单片机介绍2.单片机内部三大资源3.单片机最小系统4.STC89C52单片机 1.单片机介绍 兼容Intel的MCS-51体系架构的一系列单片机。 STC89C52:8K FLASH、512字节RAM、32个IO口、3个定时器、1个UART、8个中断源。 单片机简称MCU单片机内部集成了CPU、RAM、RO…...

网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...

【Oracle APEX开发小技巧12】
有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...

linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...

苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...
工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配
AI3D视觉的工业赋能者 迁移科技成立于2017年,作为行业领先的3D工业相机及视觉系统供应商,累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成,通过稳定、易用、高回报的AI3D视觉系统,为汽车、新能源、金属制造等行…...
JS设计模式(4):观察者模式
JS设计模式(4):观察者模式 一、引入 在开发中,我们经常会遇到这样的场景:一个对象的状态变化需要自动通知其他对象,比如: 电商平台中,商品库存变化时需要通知所有订阅该商品的用户;新闻网站中࿰…...
关于uniapp展示PDF的解决方案
在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项: 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库: npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...
C语言中提供的第三方库之哈希表实现
一. 简介 前面一篇文章简单学习了C语言中第三方库(uthash库)提供对哈希表的操作,文章如下: C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...

Neko虚拟浏览器远程协作方案:Docker+内网穿透技术部署实践
前言:本文将向开发者介绍一款创新性协作工具——Neko虚拟浏览器。在数字化协作场景中,跨地域的团队常需面对实时共享屏幕、协同编辑文档等需求。通过本指南,你将掌握在Ubuntu系统中使用容器化技术部署该工具的具体方案,并结合内网…...