装饰器
记录看别人源码过程中一些常遇到的装饰器。
@staticmethod :
@staticmethod
装饰器用于将一个方法声明为静态方法。静态方法是与类相关联的方法,但与类的实例无关,因此它们不需要访问类的实例变量或方法,也不需要访问实例本身。静态方法通常用于执行与类相关的操作,但不需要实例化类。
@staticmethod
装饰器的主要作用如下:
与类关联而不依赖于实例:静态方法属于类而不属于类的实例。这意味着你可以通过类名来调用静态方法,而无需创建类的实例。这使得它们可以在不需要类的实例的情况下执行某些操作。
避免访问实例变量:静态方法不会自动获取类的实例或类本身的引用,因此它们通常用于执行独立于类实例的操作。这意味着它们无法访问或修改实例变量,因为它们没有
self
参数。类级别的操作:静态方法通常用于执行与整个类相关的操作,例如工具函数、实用程序方法或执行不依赖于实例状态的计算。
以下是一个示例,说明了如何使用 @staticmethod
装饰器来定义和使用静态方法:
1 | class MathUtils: |
在这个示例中,add
方法是一个静态方法,它不需要类的实例,可以直接通过类名 MathUtils
来调用。静态方法在不需要访问实例状态的情况下执行一个简单的数学操作。
总之,@staticmethod
装饰器用于定义静态方法,这些方法与类相关联但与类的实例无关,可以在不创建类实例的情况下调用。它们通常用于执行与类相关的操作,但不需要访问实例变量或方法。
@property
@property
装饰器是 Python 中用于创建属性的一种方式,它可以让你定义一个方法,但可以像访问类的属性一样访问这个方法,而不需要显式地调用方法。这种方法的主要作用是将一个方法转化为只读属性,让外部代码可以更容易地访问和使用类的属性,同时隐藏内部实现的细节。
以下是 @property
装饰器的作用详解:
将方法转化为属性:
@property
装饰器可以应用于一个方法,使该方法可以像属性一样访问。这意味着你可以通过属性名来获取方法的返回值,而不需要在属性名后加括号调用方法。隐藏方法的调用:使用属性而不是方法调用可以使代码更清晰,因为它让属性的访问看起来更像变量的访问,而不是函数的调用。
允许属性访问和设置:你可以通过定义一个与属性同名的 setter 方法,使用
@property
装饰器的@属性名.setter
子装饰器,从而允许属性的设置。这使得你可以在外部代码中像操作属性一样设置属性值。实现计算属性:你可以在
@property
方法中编写复杂的逻辑,以根据类的状态计算属性的值。这样,你可以将属性视为类状态的派生值。
以下是一个示例,说明了如何使用 @property
装饰器:
1 | class Circle: |
在这个示例中,Circle
类定义了三个只读属性 radius
、diameter
和 area
,并定义了一个 setter 方法来设置 radius
属性。这使得用户可以轻松访问这些属性,同时确保 radius
的值始终为非负数。
@classmethod
在Python中,@classmethod
装饰器用于定义一个类方法(class method)。类方法是绑定到类而不是实例的方法,因此它可以在不创建类的实例的情况下被调用。通常,类方法用于执行与类本身相关的操作,而不是与实例相关的操作。
下面是 @classmethod
装饰器的详细解释:
定义类方法:
使用@classmethod
装饰器,可以将一个普通的方法转换为类方法。类方法的第一个参数通常命名为cls
,表示类本身。1
2
3
4class MyClass:
def my_class_method(cls, arg1, arg2):
# 类方法的实现调用类方法:
类方法可以通过类名直接调用,也可以通过类的实例调用。1
2
3MyClass.my_class_method(arg1, arg2) # 通过类名调用类方法
obj = MyClass()
obj.my_class_method(arg1, arg2) # 通过类的实例调用类方法类方法的特点:
- 类方法是绑定到类的,因此它可以访问类级别的属性和方法。
- 类方法不能访问实例级别的属性和方法,因为它没有对实例的引用。
- 类方法通常用于工厂方法、创建实例、或执行与类相关的操作。
下面是一个简单的示例,演示如何使用 @classmethod
装饰器定义和调用类方法:
1 | class MyClass: |
在上述示例中,@classmethod
装饰器用于定义 increment_class_variable
类方法,该方法可以增加类变量 class_variable
的值。类方法可以通过类名调用,也可以通过实例调用。
自定义的装饰器
@timer:测量执行时间
1 | import time |
@debuger:
1 | def debug(func): |