当前位置: 首页 > news >正文

【Python基础】装饰器(3848字)

文章目录

    • @[toc]
      • 闭包
      • 什么是装饰器
      • 装饰器示例
        • 不使用装饰器语法
        • 使用装饰器语法
      • 装饰器传参
      • 带参数的装饰器
      • 类装饰器
        • 魔术方法\__call__()
        • 类装饰器示例
        • 带参数类装饰器
        • property装饰器
          • 分页操作
          • 商品价格操作

因上努力

个人主页:丷从心·

系列专栏:Python基础

学习指南:Python学习指南

果上随缘


闭包

  • 在学习装饰器之前,先来了解什么是闭包:【Python基础】闭包(2157字)

什么是装饰器

  • 装饰器可以在不改变函数或类已有代码的前提下为其增加额外功能
  • 装饰器本质上是一个高阶函数,它接受一个函数或类作为输入,并返回一个新的函数或类作为输出,这个新的函数或类具有扩展或修改原始函数或类行为的功能

装饰器示例

不使用装饰器语法
def debug(func_obj):def wrapper():print(f'[DEBUG]: {func_obj.__name__}')func_obj()return wrapperdef say_hello():print('hello')say_hello = debug(say_hello)
say_hello()
[DEBUG]: say_hello
hello
  • debug(say_hello)的返回值是一个函数,使用变量say_hello进行接收,于是函数say_hello()被增加了功能
使用装饰器语法
  • 装饰器通过使用@符号紧跟在函数或类定义之前来使用
def debug(func_obj):def wrapper():print(f'[DEBUG]: {func_obj.__name__}')func_obj()return wrapper@debug
def say_hello():print('hello')say_hello()
[DEBUG]: say_hello
hello
  • 本质上@debug的作用就是执行了say_hello = debug(say_hello),为函数say_hello 增加了功能

装饰器传参

  • 如果被装饰的函数带有参数,调用时需要进行传参
def debug(func_obj):def wrapper(*args, **kwargs):print(f'[DEBUG]: {func_obj.__name__}')func_obj(*args, **kwargs)return wrapper@debug
def say(message):print(message)say('Hello, world!')
[DEBUG]: say
Hello, world!

带参数的装饰器

def level(lev):def logger(func):def wrapper(*args, **kwargs):print(f'[{lev}]: {func.__name__}')func(*args, **kwargs)return wrapperreturn logger@level('INFO')
def say(message):print(message)
[INFO]: say
Hello, world!
  • 本质上@level('INFO')的作用就是执行了say = level('INFO')(say),为函数say增加了功能
def level(lev):def logger(func):def wrapper(*args, **kwargs):print(f'[{lev}]: {func.__name__}')func(*args, **kwargs)return wrapperreturn loggerdef say(message):print(message)say = level('INFO')(say)
say('Hello, world!')
[INFO]: say
Hello, world!

类装饰器

魔术方法_call_()
  • 一个类实现了魔术方法__call__()时,当对象被调用时会自动触发__call__()方法
class Test:def __call__(self, *args, **kwargs):print('我被触发了...')test = Test()
test()
我被触发了...
类装饰器示例
class Debug:def __init__(self, func_obj):self.func_obj = func_objdef __call__(self, *args, **kwargs):print(f'[DEBUG]: {self.func_obj.__name__}')self.func_obj(*args, **kwargs)@Debug
def say(message):print(message)say('Hello, world!')
[DEBUG]: say
Hello, world!
  • 本质上@Debug的作用就是执行了say = Debug(say),为函数say增加了功能
带参数类装饰器
class Logger:def __init__(self, level='info'):self.level = leveldef __call__(self, func):def wrapper(*args, **kwargs):print(f'[{self.level}]: {func.__name__}')func(*args, **kwargs)return wrapper@Logger(level='ERROR')
def say(message):print(message)say('Hello, world!')
  • 本质上@Logger(level='ERROR')的作用就是执行了say = Logger(level='ERROR')(say),为函数say增加了功能
property装饰器
  • property装饰的方法可以看作一个实例属性,在调用时无需()
分页操作
class Page:def __init__(self, page_number):self.page_number = page_numberself.page_size = 10@propertydef start(self):val = (self.page_number - 1) * self.page_sizereturn val + 1@propertydef end(self):val = self.page_number * self.page_sizereturn valpage = Page(2)print(f'第 {page.page_number} 页, 显示第 {page.start} - {page.end} 条内容')
商品价格操作
class Goods:def __init__(self, ori_price):self.ori_price = ori_price@propertydef price(self):print('价格正在获取中...')return self.ori_price@price.setterdef price(self, new_price):print('价格正在修改中...')self.ori_price = new_price@price.deleterdef price(self):print('价格正在删除中...')goods = Goods(100)goods_price = goods.price
print(goods_price)goods.price = 200
print(goods.ori_price)del goods.price
  • 对被@property装饰的属性进行修改时,会触发被@price.setter装饰的方法
  • 删除被@property装饰的属性时,会触发被@price.deleter装饰的方法

相关文章:

【Python基础】装饰器(3848字)

文章目录 [toc]闭包什么是装饰器装饰器示例不使用装饰器语法使用装饰器语法 装饰器传参带参数的装饰器类装饰器魔术方法\__call__()类装饰器示例带参数类装饰器property装饰器分页操作商品价格操作 个人主页:丷从心 系列专栏:Python基础 学习指南&…...

十、Redis内存回收策略和机制

1、Redis的内存回收 在Redis中可以设置key的过期时间,以期可以让Redis回收内存,循环使用。在Redis中有4个命令可以设置Key的过期时间。分别为 expire、pexpire、expireat、pexpireat。 1.1、expire expire key ttl:将key的过期时间设置为tt…...

Ansible --- playbook 脚本+inventory 主机清单

一 inventory 主机清单 Inventory支持对主机进行分组,每个组内可以定义多个主机,每个主机都可以定义在任何一个或 多个主机组内。 如果是名称类似的主机,可以使用列表的方式标识各个主机。vim /etc/ansible/hosts[webservers]192.168.10.1…...

【hive】transform脚本

文档地址:https://cwiki.apache.org/confluence/display/Hive/LanguageManualTransform 一、介绍二、实现1.脚本上传到本地2.脚本上传到hdfs 三、几个需要注意的点1.脚本名不要写全路径2.using后面语句中,带不带"python"的问题3.py脚本Shebang…...

5款可用于LLMs的爬虫工具/方案

5款可用于LLMs的爬虫工具/方案 Crawl4AI 功能: 提取语义标记的数据块为JSON格式,提供干净的HTML和Markdown文件。 用途: 适用于RAG(检索增强生成)、微调以及AI聊天机器人的开发。 特点: 高效数据提取,支持LLM格式,多U…...

投影、选择转SQL语言

使用以下两个表进行举例,第一个表为R表,第二个表为S表 R.AR.BR.C123456789 S.AS.BS.C101112131415161718 1、投影转SQL语言: 兀 A,B,C (R) 等价于select A,B,C from R 解释: 兀:相当于select (R):相当于from R…...

系统加固-自用

一、windows 1、概述 (1)、权限最高:system(系统账户),权限比administrator权限还高 (2)、常见操作系统安全漏洞类型 缓冲区溢出漏洞TCP/IP协议漏洞web应用安全漏洞开放端口的安全漏洞 2、系统安全加固方法 (1)、系统不显示上次登录的用户名 进入…...

Java面试题:阐述Java中的自动装箱与拆箱机制,以及使用它们时可能遇到的性能问题

在Java中,自动装箱(Autoboxing)和拆箱(Unboxing)是Java 5引入的特性,它们允许基本数据类型和对应的包装类之间的自动转换。 自动装箱 自动装箱是指将基本数据类型(如int、double等&#xff09…...

初识sql注入--手工注入

目录 可能使用的sql函数 入侵网站方式 1、文件上传漏洞 2、rce 3、sql注入 SQL注入 什么是sql注入 进行SQL注入 实验环境 开始实验(使用information_shema数据库) 1、进入靶场 2、报列数 下面来解释一下为什么要照上面SQL语句写 url编码 单…...

OceanBase 缺少 dbms_obfuscation_toolkit.md5 包函数的解决方案

因为 dbms_obfuscation_toolkit.md5 是一个 Oracle 不推荐继续使用的函数,所以 OceanBase 没有对其兼容,取而代之的是兼容了 dbms_crypto.hash,其用法详见这篇 KB 但是,并不是所有业务都接受修改源码,因为复杂系统里&…...

Java---类和对象第一节

目录 1.面向对象初步认识 1.1什么是面向对象 1.2面向对象和面向过程的区别 2.类的定义和使用 2.1简单认识类 2.2类的定义格式 2.3类的实例化 2.4类和对象的说明 3.this关键字 3.1访问本类成员变量 3.2调用构造方法初始化成员变量 3.3this引用的特性 4.对象的构造以…...

Zeller公式的应用:给定日期,确定周几

开篇 本篇文章依然是对于日期相关函数的实现。 问题概要 给定一个日期&#xff0c;返回为周几 思路分析 这个问题的思路只是对于Zeller公式的直接引用&#xff0c;不存在其他逻辑。公式详情可参考Zeller公式百科 代码实现 #include <stdio.h>// 根据Zeller公式计算 int …...

程序链接和运行 - 笔记

1 linux下程序a连接b.so后,运行时如何找到调用的函数 在Linux下,当程序A连接了动态链接库B(.so文件)后,在运行时,程序A会使用动态链接器(dynamic linker)来解析并加载动态链接库B中的函数。动态链接器会在系统中搜索动态链接库,并将它们加载到程序的地址空间中。 当…...

pyqt 按钮常用格式Qss设置

pyqt 按钮常用格式Qss设置 QSS介绍按钮常用的QSS设置效果代码 QSS介绍 Qt Style Sheets (QSS) 是 Qt 框架中用于定制应用程序界面样式的一种语言。它类似于网页开发中的 CSS&#xff08;Cascading Style Sheets&#xff09;&#xff0c;但专门为 Qt 应用程序设计。使用 QSS&am…...

websevere服务器从零搭建到上线(一)|阻塞、非阻塞、同步、异步

文章目录 数据准备(阻塞和非阻塞)、数据读写(同步和异步)小总结&#xff08;陈硕老师的总结&#xff09; 知识拓展同步执行实例异步编程实例 八股 数据准备(阻塞和非阻塞)、数据读写(同步和异步) 无论是什么样的IO都包含两个阶段&#xff1a;数据准备和数据读写。 我们的网络IO…...

【C++】引用传递 常量引用

在C中&#xff0c;引用传递和常量引用是两个常用的概念&#xff0c;主要用于函数参数传递。它们提供了对变量或对象更有效率和更安全的访问方式。 引用传递&#xff08;Pass by Reference&#xff09; 引用传递意味着当你将变量作为参数传递给函数时&#xff0c;你实际上是传…...

Docker停止不了

报错信息 意思是&#xff0c;docker.socket可能也会把docker服务启动起来 解决 检查服务状态 systemctl status dockersystemctl is-enabled docker停止docker.socket systemctl stop docker.socket停止docker systemctl stop docker知识扩展 安装了docker后&#xff0c;…...

【网络】为什么TCP需要四次挥手?

在网络通信中&#xff0c;TCP&#xff08;传输控制协议&#xff09;是一种可靠的、面向连接的协议&#xff0c;它在数据传输过程中保证了数据的可靠性和顺序性。而TCP的连接建立过程只需要三次握手&#xff0c;但是TCP的挥手过程却需要四次挥手&#xff0c;这是为什么呢&#x…...

2024自动化测试市场分析

大家都说2024年软件测试讲会卷的更厉害,从原来的功能测试到现在自动化测试,那么2024年是否可以学习自动化冲一把,我们先看一下2023年自动化测试在测试行业中的分析: 1.市场需求增长&#xff1a; 随着技术的进步和企业对软件质量的要求日益提高&#xff0c;自动化测试在测试行…...

什么是机器视觉应用解决方案?

机器视觉应用解决方案通常指的是利用视觉系统自动检测、处理和分析图像的技术方案&#xff0c;以便执行各种工业或研究任务&#xff0c;如质量控制、自动检测、导航和识别等。在LabVIEW环境中&#xff0c;这些解决方案通常涉及到硬件和软件的紧密集成&#xff0c;以实现高效的数…...

linux之kylin系统nginx的安装

一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源&#xff08;HTML/CSS/图片等&#xff09;&#xff0c;响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址&#xff0c;提高安全性 3.负载均衡服务器 支持多种策略分发流量…...

通过Wrangler CLI在worker中创建数据库和表

官方使用文档&#xff1a;Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后&#xff0c;会在本地和远程创建数据库&#xff1a; npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库&#xff1a; 现在&#xff0c;您的Cloudfla…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命

在华东塑料包装行业面临限塑令深度调整的背景下&#xff0c;江苏艾立泰以一场跨国资源接力的创新实践&#xff0c;重新定义了绿色供应链的边界。 跨国回收网络&#xff1a;废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点&#xff0c;将海外废弃包装箱通过标准…...

Redis数据倾斜问题解决

Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中&#xff0c;部分节点存储的数据量或访问量远高于其他节点&#xff0c;导致这些节点负载过高&#xff0c;影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...

Typeerror: cannot read properties of undefined (reading ‘XXX‘)

最近需要在离线机器上运行软件&#xff0c;所以得把软件用docker打包起来&#xff0c;大部分功能都没问题&#xff0c;出了一个奇怪的事情。同样的代码&#xff0c;在本机上用vscode可以运行起来&#xff0c;但是打包之后在docker里出现了问题。使用的是dialog组件&#xff0c;…...

rnn判断string中第一次出现a的下标

# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...

C++.OpenGL (14/64)多光源(Multiple Lights)

多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...

vulnyx Blogger writeup

信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面&#xff0c;gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress&#xff0c;说明目标所使用的cms是wordpress&#xff0c;访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...

安卓基础(Java 和 Gradle 版本)

1. 设置项目的 JDK 版本 方法1&#xff1a;通过 Project Structure File → Project Structure... (或按 CtrlAltShiftS) 左侧选择 SDK Location 在 Gradle Settings 部分&#xff0c;设置 Gradle JDK 方法2&#xff1a;通过 Settings File → Settings... (或 CtrlAltS)…...