Python 静态方法与类方法详解

1. 写法上的差异

类的方法可以分为:

  1. 静态方法:有 staticmethod 装饰的函数
  2. 类方法:有 classmethod 装饰的函数
  3. 实例方法:没有任何装饰器的普通函数

举个例子,如下这段代码中,run 普通的实例方法,eat 是静态方法,jump 是类方法。

class Animal:
    def __init__(self, name):
        self.name = name

    def run(self):
        print(f"{self.name}跑起来啦")

    @staticmethod
    def eat():
        print("正在吃饭...")

    @classmethod
    def jump(cls, name):
        print(f"{name}跳起来啦")

这三种方法,在写法有很大的区别:

1、普通的实例方法,在定义时,他的第一个方法固定是 self,如果是从实例调用,那么 self 参数 不需要传入,如果是通过类调用,那么 self 要传入已经实例化的对象。

>>> dog=Animal(name="小黑")
>>> dog.run()
小黑跑起来啦
>>> Animal.run(dog)
小黑跑起来啦

2、静态方法,在定义时,不需要 self 参数。

>>> dog=Animal(name="小黑")
>>> dog.eat()
正在吃饭...
>>> Animal.eat()
正在吃饭...

3、类方法,在定义时,第一个参数固定是 cls,为 class 的简写,代表类本身。不管是通过实例还是类调用类方法,都不需要传入 cls 的参数。

>>> dog=Animal(name="小黑")
>>> dog.jump("小黑")
小黑跳起来啦
>>> Animal.jump("小黑")
小黑跳起来啦

2. 方法与函数区别

在前面,我们很经常提到方法和函数,为免有同学将他们混为一谈,我这里总结一下他们的区别。

在 Python 3.x 中,

  1. 普通函数(未定位在类里)和静态方法,都是函数(function )。

  2. 实例方法(@staticmethod)和类方法,都是方法(method )。

这些结论其实都可以使用 type 函数得到验证。

先准备如下代码

class Animal:
    def __init__(self, name):
        self.name = name

    def run(self):
        print(f"{self.name}跑起来啦")

    @staticmethod
    def eat():
        print("正在吃饭...")

    @classmethod
    def jump(cls, name):
        print(f"{name}跳起来啦")

def demo_func():
    pass

然后进入 Python Console 模式

>>> type(demo_func)  # 普通函数
<class 'function'>
>>> type(dog.eat)   # 静态方法
<class 'function'>
>>>
>>> type(dog.run)  # 实例方法
<class 'method'>
>>> type(dog.jump)  # 类方法
<class 'method'>

到这里,你应该会有疑问了吧?

类方法和实例方法,名字本身就有方法,也是方法也说得过去。那静态方法呢,为什么不是方法而是函数呢?

对此,我的理解是:方法是一种和对象(实例或者类)绑定后的特殊函数。

方法本质上还是函数,不同之处在于它与对象进行绑定。

教程来源于Github,感谢iswbm大佬的无私奉献,致敬!

技术教程推荐

Service Mesh实践指南 -〔周晶〕

从0开始做增长 -〔刘津〕

许式伟的架构课 -〔许式伟〕

透视HTTP协议 -〔罗剑锋(Chrono)〕

Django快速开发实战 -〔吕召刚〕

如何读懂一首诗 -〔王天博〕

大数据经典论文解读 -〔徐文浩〕

郭东白的架构课 -〔郭东白〕

深入C语言和程序运行原理 -〔于航〕