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

【测试开发】函数高阶-闭包、装饰器

一、闭包

1、闭包的概念

一个完整的闭包必须满足以下条件

  1. 函数中嵌套一个函数
  2. 外层函数返回内层函数的变量名
  3. 内层函数对外部作用域有一个非全局的变量进行引用

2、闭包案例

  • 不带参数的
def func():print('------func函数被调用------')num = 100def count_book():  # 函数内部的局部变量的命名空间print(num) # 内层嵌套函数引用了外层的一个非全局变量print('这个是count_book函数')return count_bookres = func()
res()
# print(type(res)) # 返回的是function类
  • 带参数的
def func(num):print('------func函数被调用------')def count_book():  # 函数内部的局部变量的命名空间print(num) # 内层嵌套函数引用了外层的一个非全局变量print('这个是count_book函数')return count_bookres = func(100)
res()
# print(type(res)) # 返回的是function类

二、装饰器

  • 面向对象原则的核心:开放封闭原则

1、开放封闭原则

软件实体应该是可扩展,而不可修改的,即对扩展是开放的,而对修改是封闭的。

2、装饰器的作用

在不更改原功能函数内部代码,且不改变调用方法的情况下为原函数添加新的功能

3、装饰器的应用场景

  • 登录验证
  • 函数运行时间统计
  • 执行函数之前做准备工作
  • 执行函数后清理功能

4、实现一个不带参数的装饰器

# 不带参数的装饰器def login(func):  # 闭包函数中的接收的参数就是内部传进去的函数def fun():username = 'wanzi'password = 'youyou'user = input("请输入账号:")pw = input("请输入密码:")if username == user and pw == password:func()  # index.__closure__ 传进去的index在closure属性中else:print("账号或密码错误")return fun@login # @login:语法糖 -->index = login(index)
def index():print('这个是网站的首页')index() # 调用index相当于调用fun()# 以下两行代码作用=@login
# index = login(index)
# index()

5、实现一个带参数的装饰器

# 带参数的装饰器def add(func): # 括号内接收的是一个函数def fun(a,b):print('相乘:', a * b)print('相除:', a / b)func(a,b)return fun@add
def add_num(a,b):# 打印两个数相加print('相加:', a+b)add_num(1,2)

三、装饰器装饰类

装饰器装饰类必须写return返回对象,装饰函数不需要

若多个装饰器装饰了同一个函数,则从下往上装饰,从上往下执行

# 装饰器装饰类
def add(func):def fun(*args, **kwargs):print("装饰器的功能代码")return func(*args, **kwargs)return fun@add  # MyClass = add(MyClass)
class MyClass:def __init__(self, name, age):self.name = nameself.age = agem = MyClass('丸子', 18)
print(m.name)
print(m.age)

四、内置装饰器

Python中的内置装饰器,均是在类中使用,不能在类外面使用

1、@classmethod

  • 类方法不能直接调用实例的方法,被@classmethod装饰后,可以调用
  • 类属性、类方法可以被实例调用
  • 类方法可以被类调用,也可以被实例属性调用
  • 类无法调用实例属性和实例方法

2、@staticmethod 静态方法

不带参数,实例和类都可以调用


class MyTest(object):@classmethod # 被classmethod装饰之后,该方法就是一个类方法def add(cls): # cls代表的是类本身print('add')print(cls)@staticmethoddef static():print('static静态方法')def sub(self): # self代表的是实例本身print('sub')t = MyTest()
t.add()
t.static()
t.sub()

3、@property

一般用于设置只读属性,装饰完后被装饰的方法可以像属性一样被调用

class MyTest(object):def __init__(self, name):self.name = name@property  # 设定只读属性 被装饰的方法可以像属性一样被调用def read_attr(self):return '18岁't = MyTest('优优')
t.name = '丸子' # 支持修改
print('name的值:', t.name)
t.read_attr = '19' # 不支持修改 带@property装饰后只能读不能改  防止属性被篡改
print(t.read_attr)

http://www.xdnf.cn/news/1027855.html

相关文章:

  • P25:LSTM实现糖尿病探索与预测
  • Spring AOP与代理模式
  • 利用 Python 爬虫按关键字搜索 1688 商品
  • mvnd-快速打包maven项目
  • 如何使用自动化测试来提高接口测试的效率
  • 1Panel 618 年中大促|不止半价!
  • 《二叉堆》题集
  • Ubuntu VMware虚拟机卡在/dev/sda1
  • ubuntu调整硬盘大小-使用gparted
  • 板子接入mipi摄像头
  • HTML+CSS 动态菜单和登录框
  • 共建数据强国:政务数据共享的双轮革命
  • 【力扣 简单 C】160. 相交链表
  • C++笔记-C++11(三)
  • 【Spring AI】MCP Server实现多实例部署
  • 【灵动Mini-F5265-OB】ADC之片内温度传感器与参考电压获取
  • springboot+vue大文件断点续传
  • 04 dnsmasq 的环境搭建
  • 【MIPI屏幕调试记录】个人记录用
  • Python+requests+pytest接口自动化测试框架的搭建
  • 专项提升-分析dump堆文件 服务器内存占用排查
  • 在死胡同里 做加法是什么意思?
  • 坚持做一件事情和好奇做一件事,本质区别和思考
  • 开发者视角:一键拉起功能解析
  • XAttention 计算步骤详解及示例
  • 【Qt】Qt控件
  • 【组件】纯html+css实现图片预览+切换图片的功能
  • 189. 轮转数组
  • Linux --基础IO
  • 大模型的开发应用(十):对话风格微调项目(上):数据工程与模型选型