当前位置:首页>python>Python学习【81】:python的面向对象:详解@staticmethod和@classmethod

Python学习【81】:python的面向对象:详解@staticmethod和@classmethod

  • 2026-10-21 13:29:55
Python学习【81】:python的面向对象:详解@staticmethod和@classmethod

Python学习

一、学前花絮

我们之前学习了python的面向对象,针对类/对象、init方法及操作动态属性等进行了探讨。后来也学习了装饰器,装饰器是干什么的?简单说就如同装修房子,没有破坏房子但让房子更好用更美观。装饰器也是一样,让不破坏函数让函数更好用更美观。

今天结合python内置装饰器@staticmethod和@classmethod深入了解一下类内部方法的定义和使用。

二、Python面向对象:详解@staticmethod和@classmethod

2.1 静态方法(@staitcmethod)

在 Python 中,@staticmethod 是一个装饰器,用于将类中的某个方法定义为静态方法。简单来说,它的核心作用是:将一个普通函数“塞”进类里面,让它成为类的一部分,但这个函数既不操作类本身,也不操作具体的实例对象。

① 核心特点:

不需要 self 和 cls:

普通方法需要 self(代表实例),类方法需要 cls(代表类),但静态方法不需要这两个参数。它就像一个独立的普通函数,只是恰好放在了类的命名空间里。

② 无需实例化即可调用:

你可以直接通过 类名.方法名() 来调用它,不需要先创建对象(obj = MyClass())。

不能访问实例或类的状态:

因为它拿不到 self 或 cls,所以它无法读取或修改实例的属性(self.attr)或类的属性(cls.attr)。

③ 什么时候使用它?

当你发现某个功能逻辑上与这个类相关,但代码实现上不依赖于类的属性或实例的属性时,就非常适合使用 @staticmethod。

常见的场景包括:

工具函数:比如数据验证、格式转换、数学计算等。我们之前有篇文章探讨“operator”的使用,就是把加减乘除封装成工具函数。

逻辑分组:为了代码结构清晰,把相关的函数都放在同一个类里管理。

④ 代码示例:

以上程序中,instance_method是典型的实例方法,也是大多数类中所规定的方法,第一个参数必须是self。它的好处是可以很方便获取实例属性。而被装饰器的add、validate_positive方法就是静态方法,有了@staticmethod告诉使用者,直接使用此函数,无需传入类或者实例参数。

以下是调用方法:

结果如下:

这里需要说明的是,尽管@staticmethod装饰器就是为了让add等函数使用起来简单,无需实例化。但实例化后的对象是否能调用它呢?答案是可以!

输出结果:

但这种调用方法只能说是为了满足好奇心。毕竟这与@staticmethod的初衷相违背。

2.2 类方法 (@classmethod)

类方法的特点:

l必须接收类本身作为第一个隐式参数(通常命名为 cls)。

lPython 解释器会自动把调用该方法的那个类(或子类)传给 cls。

l如果把 add 改为类方法,它的定义必须是 add(cls, x, y)。

类方法与静态方法对比:

① 静态方法:

孤岛模式:它完全不知道外面的类长什么样。它不能访问类的属性(如 PI),也不能调用类的其他方法。

它就像一个被借住在类家里的“客人”。

② 类方法:

内部通达:它可以通过 cls 参数访问类的所有属性和其它类方法。

如果你的 add 运算需要用到类里的某个常量(比如税率、圆周率等),或者需要记录一下“这个方法被调用了多少次”,那就必须用类方法。

代码实战对比:

我们看到,以上的两个函数都是实现加法,但传入的参数不同。静态方法最简洁,而类方法必须传入类本身作为参数。

调用方法:

输出结果:

既然二者调用方法和输出结果看上去一样,那么选哪个呢?如果函数体内部用不到 cls(类方法)或 self(实例方法),那就坚决使用 @staticmethod。这符合“简单就是美”的编程哲学。

或者说如果只是实现类似operator的工具类,那么就用静态方法。

2.3 基本无意义(可以看做是畸形)的类方法

其实,为了透彻理解类/对象及其方法,还有一种初学者容易错误定义的类方法。可以认为是畸形的类方法,因为来源于从函数转型过来,还没有实例的概念。比如

这种函数如果不在类的内部是OK的,就是一个加法函数。但如果在类的内部,就很奇葩了。因为前面说过,类的方法基本上都能实例化调用,而这个畸形函数是无法实例化调用的,只能通过类调用。

输出结果:

尽管这种方法也确实能够使用,但它存在的意义是什么呢?结合前面学习的内容,我们会发现此类函数几乎无意义,只是为了挑战我们对于python基础知识的掌握是否稳固。

2.4 结论

虽然你可以定义一个没有 self 的普通函数放在类里,但为了代码的健壮性和可读性,只要是不需要 self 的函数,请务必加上 @staticmethod 装饰器。

三、小结

通过学习python面向对象及内置装饰器@staticmethod、@classmethod,我们对于类/对象及其方法的使用又有了新的认识。

让我们保持学习热情,多做练习。我们下期再见!

最新文章

随机文章