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

Python中内置的常用装饰器

装饰器的详细介绍和定义参看这篇:
python中的装饰器_python 定义装饰器-CSDN博客

这篇博客主要是简单介绍装饰器作用,并列举常用的几个装饰器。(面试被问到了(;′⌒`))


python中的装饰器Decorator 是python中的一个高级特性,它允许不修改函数代码的前提下,动态地给函数增加功能。

装饰器的本质是一个函数或类,它接受一个函数的输入,并返回一个新函数,这个函数通常是对原函数的扩展或者修改。

装饰器的作用和优势:
1. 代码复用:将某些通用功能(日志、缓存)封装为装饰器,多个函数可以复用。

2. 增强函数功能

3. 符合开放-关闭原则: 对扩展开放,对修改封闭。

常用装饰器

@property 属性装饰器

作用:把一个方法变成属性调用,允许通过属性方式访问计算结果。

属性是什么?

“属性”是面向对象编程(OOP)中的一个重要概念。简单来说,属性就是对象所拥有的数据或状态,用来描述对象的特征。

  • 属性(Attribute) 是对象的一个数据成员,用于存储对象的状态信息。
  • 属性一般以变量的形式存在于类的实例中。
  • 属性用来描述对象的特征或状态,比如人的姓名、年龄,圆的半径、颜色等。
class Circle:def __init__(self, radius):self._radius = radius@propertydef area(self):return 3.14159 * self._radius ** 2c = Circle(5)
print(c.area)

如果不用装饰器:

class Circle:def __init__(self, radius):self._radius = radiusdef area(self):return 3.14159 * self._radius ** 2c = Circle(5)
print(c.area())  # 注意这里需要调用方法

@staticmethod 静态方法装饰器

不需要实例和类作为参数,类似普通函数。不需要接收实例(self)或类(cls)作为第一个参数

换句话说,静态方法就像是放在类命名空间中的普通函数,它既不像实例方法那样隐式传入实例引用,也不像类方法那样隐式传入类引用。

作用是什么?

一个静态方法和定义在类外的普通函数,从技术上调用方式类似,但静态方法被放到类的命名空间内,有两个优点:

  • 命名空间组织:让函数的含义和类相关联。
  • 代码可读性增强:调用时通过类名点调用,能表达逻辑关联

使用场景:

  • 工具函数:实现与类逻辑相关,但不依赖实例或类状态的辅助功能。比如格式化数据、计算公式等。

  • 组织代码结构:把函数放在类中,体现逻辑上的归属关系,而非放在全局命名空间。

class MyClass:@staticmethoddef static_method():print("这是静态方法")MyClass.static_method()

不使用@staticmethod,直接在类中定义一个普通函数会报错:

class Utils:def add(x, y):return x + y# 类调用
print(Utils.add(1, 2))  # 输出: 3# 实例调用
u = Utils()
# print(u.add(3, 4))    # 这样会报错:TypeError: add() takes 2 positional arguments but 3 were given
  • 直接用 Utils.add(1,2) 没问题;
  • 但用实例 u.add(3,4) 时,Python会自动把 u 作为第一个参数传入,即 add(u, 3, 4),导致参数数量不对,报错

使用@staticmethod:

class Utils:@staticmethoddef add(x, y):return x + y# 类调用
print(Utils.add(1, 2))  # 输出: 3# 实例调用
u = Utils()
print(u.add(3, 4))      # 输出: 7

@classmethod 类方法装饰器

用于将类中的方法定义为类方法,类方法的第一个参数必须是类本身(通常命名为 cls),而不是实例(self

class MyClass:@classmethoddef my_class_method(cls, arg1, arg2):print(f"cls: {cls}")print(f"arg1: {arg1}, arg2: {arg2}")
# 方法1
MyClass.my_class_method(1, 2)
# 方法2
obj = MyClass()
obj.my_class_method(3, 4)

两种调用方式,无论怎么调用,Python 都会自动将实际调用者的类作为第一个参数 cls 传入。

应用场景:

  • 工厂方法:类方法常用作工厂函数,返回当前类的不同实例。
  • 访问或修改类属性:类方法可用于访问或修改类级别的属性,对所有实例生效。
  • 子类化友好:类方法可以自动识别是哪一个子类调用,从而实例化正确的类型。

未使用@classmethod  vs 使用

情况一

未使用:

class Animal:def __init__(self, name, age):self.name = nameself.age = age# 静态方法版本@staticmethoddef from_birth_year(name, birth_year):current_year = 2024age = current_year - birth_year# 只能硬编码类名,无法兼容继承return Animal(name, age)class Dog(Animal):passdog = Dog.from_birth_year("Buddy", 2015)
print(type(dog))  # <class '__main__.Animal'>   ←返回的是父类Animal,不是Dog

使用:

class Animal:def __init__(self, name, age):self.name = nameself.age = age@classmethoddef from_birth_year(cls, name, birth_year):current_year = 2024age = current_year - birth_year# 用cls来创建实例,兼容继承return cls(name, age)class Dog(Animal):passdog = Dog.from_birth_year("Buddy", 2015)
print(type(dog))  # <class '__main__.Dog'>      ←返回的是Dog实例

情况二
未使用:

class Counter:count = 0def increase(self):# 如果这里写 self.count += 1,其实是修改实例属性,而不是类属性self.count += 1c1 = Counter()
c2 = Counter()
c1.increase()
c2.increase()
print(Counter.count)  # 输出: 0
print(c1.count)       # 输出: 1
print(c2.count)       # 输出: 1
  • 实例方法修改的其实是实例自己的属性,不会影响整个类。

使用:

class Counter:count = 0@classmethoddef increase(cls):cls.count += 1Counter.increase()
Counter.increase()
print(Counter.count)  # 输出: 2
  • 通过 cls.count 直接修改类属性,影响所有实例。

装饰器是什么时候执行的?类定义还是实例化?

答:在类定义的时候就被执行,修改函数对象,实例化对象的时候装饰器已经生效了。

http://www.dtcms.com/a/466132.html

相关文章:

  • 年度进化挑战:从“前端实现者”到“智能体协作者”与“复杂问题定义者”
  • 靠谱的CC公益站
  • 做网站哪家便宜如何做企业招聘网站
  • HI3798MV100 运营商机顶盒NAS LINUX OS - IP地址静态绑定指南
  • 外贸网站建设公司价格湛江建站程序
  • 第三章:字符串增强与模板字符串
  • 网站开发建设技术规范书没经验可以做电商运营吗
  • Jira:设置语言 / 创建史诗 / 创建冲刺 / 创建问题
  • CancellationToken与Abort
  • linux达梦数据库操作
  • [自荐]一款mac电脑历史剪切板工具,类似著名的Paste
  • 二级域名可以做不同的网站吗网站建设网络推广广告语
  • MapReduce简介
  • FreeType 2.7 – 卓越的 Linux 字体质量
  • 龙江建站技术wordpress 管理 主题
  • 企业网站建设 制作网站建设基本流程流程图
  • 【Homebrew安装 MySQL 】macOS 用 Homebrew 安装 MySQL 完整教程
  • 【图像处理基石】暗光增强算法入门:从原理到实战(Python+OpenCV)
  • Asp.net core Kestrel服务器详解
  • OpenFeign使用
  • 如何在鸿蒙中实现毫秒级数据检索?哈希表与二分查找的双引擎优化方案
  • 实现支持链式调用的 JavaScript 类
  • 中文wordpress模板免费seo教程分享
  • 如何用ps做网站顺德网站建设7starry
  • 京东agent之joyagent解读
  • 【第五章:计算机视觉-项目实战之生成式算法实战:扩散模型】3.生成式算法实战:扩散模型-(2)DDPM数据读取
  • UCC21530-Q1 隔离栅极驱动器完全解析:从原理到实战应用
  • 企业网站的网络营销功能wordpress 发视频
  • 创作纪念日
  • 直接找高校研究生做网站行吗公众号开发单位