背景:Python中,在使用类的方法时,往往需要先对类进行实例化,然后通过实例化对象调用类的方法,例如,现有一个MathUtils类,他包含两个方法,一个用于计算圆的面积,另一个用于计算正方形的面积。
import math
class MathUtils:
def circle_area(self, r):
"""计算圆的面积,并保留两位小数"""
return round(math.pi*r**2, 2)
def squre_area(self, a):
"""计算正方形的面积"""
return a * a
if __name__ == "__main__":
math_utils = MathUtils()
circle_area = math_utils.circle_area(10)
print(f'圆的面积: {circle_area}')
squre_area = math_utils.squre_area(10)
print(f'正方形面积: {squre_area}')
为了简化这些编程,可以让程序员不再写实例化的代码就可以直接调用类的方法(这对于某些使用非常广泛且功能单一的函数来说很有意义),python3.x 版本之后不仅提供了修饰器 @staticmethod,用来修饰哪些方法是静态方法;还提供了修饰器 @classmethod,用来修饰哪些方法是类方法。静态方法和类方法都可以直接使用类名调用,这样不需要实例化对象也可以调用这些方法。下面通过上述代码的修改进行说明:
import math
class MathUtils:
@classmethod # 声明为类方法,第一个参数必须为类本身
def circle_area(self, r):
"""计算圆的面积,并保留两位小数"""
return round(math.pi*r**2, 2)
@staticmethod
def squre_area(a): # 声明为静态方法,参数中吗没有类对象参数
"""计算正方形的面积"""
return a * a
if __name__ == "__main__":
# 可以不用实例化对象调用这些类的方法,从而简化编程
circle_area1 = MathUtils.circle_area(10)
print(f'圆的面积: {circle_area1}')
squre_area1 = MathUtils.squre_area(10)
print(f'正方形面积: {squre_area1}')
# 当然,也可以通过实例化对象调用它们
math_utils = MathUtils()
circle_area2 = math_utils.circle_area(5)
print(f'圆的面积: {circle_area2}')
squre_area2 = math_utils.squre_area(5)
print(f'正方形面积: {squre_area2}')
上述代码中,修饰器 @classmethod 表示 circle_area 为类方法,此时该方法的第一个参数必须为类对象本身,一般按Python规范命名为 cls(代码中我习惯了写self);修饰器 @staticmethod表示 squre_area 是静态方法,和类方法不同的是,静态方法不要求参数中存在类对象本身。
此外,代码中展示了调用这两个方法可以直接使用类名,也可以通过实例化调用。
补充:
实际上,Python内置了3种装饰器,除了上述两种,还有一个是 @property 也比较常用
关于 @property 的使用可以参考该博客:Python @property装饰器详解,个人觉得解释的非常好,点赞加收藏。