理解method(实例方法), staticmethod(静态方法)和classmethod(类方法)的区别

本文通过实例解析Python中实例方法、类方法和静态方法的定义、调用方式和适用场景,助您理解并有效运用这些技术提高代码可维护性。

1.概述

Python中定义在类中的函数称作方法,  可以通过装饰器@staticmethod  和@classmethod将其转换成静态方法, 和类方法. 

本文将通过实例帮大家理解其中的区别, 以便明确他们的使用场景, 可以熟练使用来写出更易于维护的代码。

让我们首先编写一个类,其中包含所有三种方法类型的简单示例:

class Demo:
    def method(self, x):
        print("instance mathod", self, x)

    @classmethod
    def klass(cls, x):   # 第一个参数是cls
        print("instance mathod", cls, x)

    @staticmethod
    def static(x):        # 没有self 或 cls参数
        print("instance mathod", x)

demo = Demo()

1. 实例方法

第一个方法method,是一个常规实例方法。这是我们大部分时间都会使用的基本的方法类型。可以看到该方法接受一个参数,self,该参数指向demo(该方法被调用时的实例对象).

通过self参数,实例方法可以自由访问同一对象上的属性和其他方法.

>>> demo.method(1)
instance mathod:  <__main__.Demo object at 0x0000021BDC4864C8> 1

通过 <instance>.<method> 语法调用实例方法时, Python隐式的将实例对象赋值给self参数. 等价于class.method(instance)

>>> Demo.method(demo, 1)
instance mathod:  <__main__.Demo object at 0x0000021BDC4864C8> 1

2. 类方法

将实例方法method和类方法klass对比, 发现类方法第一个参数不是self,而是cls指向类而非对象实例的参数. cls指向的类对象而不是实例.

类对象不能调用实例方法, 可以直接调用类方法, 调用类方法时, 隐式的将类对象赋值给cls参数.

>>> Demo.klass(1)
instance mathod:  <class '__main__.Demo'> 1

实例对象也可以调用类方法

>>> demo.klass(1)
instance mathod:  <class '__main__.Demo'> 1

什么时候使用类方法?

类方法的常见使用场景,作为工厂函数创建实例对象

class Pizza:
    def __init__(self, ingredients):
        self.ingredients = ingredients

    def __repr__(self):
        return f'Pizza({self.ingredients!r})'

    @classmethod
    def margherita(cls):
        return cls(['mozzarella', 'tomatoes'])

    @classmethod
    def prosciutto(cls):
        return cls(['mozzarella', 'tomatoes', 'ham'])

3. 静态方法

使用@staticmethod装饰器的方法被转换为静态方法, 这种类型的方法既不接受 self也不接受cls参数。静态方法可以理解为定义在类作用域内的一个函数, 而不是方法. 可以通过类和实例对象直接调用

>>> demo.static(2)  # 通过实例调用
instance mathod:  2

>>> Demo.static(2)  # 通过类调用
instance mathod:  2

什么时候使用静态方法?

静态方法只是名义上归这个类管理, 为什么放到类里面呢, 一个原因是为了增加可读性.

class Dates:
    def __init__(self, date):
        self.date = date

    @staticmethod
    def to_dash_date(date):
        return date.replace("/", "-")

    @staticmethod
    def to_slash_date(date):
        return date.replace("-", "/")

另一个使用场景, 当父类中的有些方法不希望类的子类更改/覆盖方法的特定实现时,使用静态方法 

 2. 对比

方法类型被实例调用被类调用访问实例属性访问类属性
实例方法
类方法
静态方法

 总结:

  1. 实例方法需要一个类实例, 可以通过self访问实例对象的方法和属性
  2. 类方法不需要实例, 可以通过cls访问类的属性和类方法
  3. 静态方法不能访问clsself, 它们像常规函数一样工作,但属于类的命名空间。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值