72 成员方法、类方法、静态方法、抽象方法

在面向对象程序设计中,函数和方法这两个概念是有本质区别的。方法一般指与特定实例绑定的函数,通过对象调用方法时,对象本身将被作为第一个参数自动传递过去,普通函数并不具备这个特点。

class Demo:
    pass


t = Demo()


def test(self, v):
    self.value = v


t.test = test  # 动态增加普通函数
print(t.test)
t.test(t, 3)  # 需要为 self 传递参数
print(t.value)

import types

t.test = types.MethodType(test, t)  # 动态增加绑定的方法
print(t.test)
t.test(5)  # 不需要为 self 传递参数
print(t.value)

在这里插入图片描述

Python 类的成员方法大致可以分为公有方法、私有方法、静态方法、类方法和抽象方法这几种类型。

① 公有方法、私有方法和抽象方法一般是指属于对象的实例方法,私有方法的的名字以两个或更多个下画线开始,而抽象方法一般定义在抽象类中并且要求派生类必须重新实现。

每个对象都有自己的公有方法和私有方法,在这两类方法中都可以访问属于类和对象的成员。公有方法通过对象名直接调用,私有方法不能通过对象名调用,只能在其他实例方法中通过前缀 self 进行调用或在外部通过特殊的形式来调用。另外,Python 中的类还支持大量的特殊方法,这些方法的两侧各有两个下画线,往往与某个运算符或内置函数相对应。

所有实例方法(包括公有方法、私有方法、抽象方法和某些特殊方法)都必须至少有一个名为 self 的参数,并且必须是方法的第一个形参(如果有多个形参), self 参数代表当前对象。 在实例方法中访问实例成员时需要以 self 为前缀,但在外部通过对象名调用对象方法时并不需要传递这个参数。如果在外部通过类名调用属于对象的公有方法,需要显示为该方法的 self 参数传递一个对象名,用来明确指定访问哪个对象的成员。

静态方法和类方法都可以通过类名和对象名调用,但不能直接访问属于对象的成员,只能访问属于类的成员。 静态方法和类方法不属于任何实例,不会绑定到任何实例,当然也不依赖于任何实例的状态,与实例方法相比能够减少很多开销。类方法一般以 cls 作为第一个参数表示该类自身,在调用类方法时不需要为该参数传递值,静态方法则可以接收任何参数。

class Root:
    __total = 0

    def __init__(self, v):  # 构造方法,特殊方法
        self.__value = v
        Root.__total += 1

    def show(self):  # 普通实例方法,一般以 self 作为第一个参数的名字
        print('self.__value: ', self.__value)
        print('Root.__total: ', Root.__total)

    @classmethod  # 修饰器,声明类方法
    def classShowTotal(cls):  # 类方法,一般以 cls 作为第一个参数的名字
        print('cls.__total: ', cls.__total)

    @staticmethod  # 修饰器,声明静态方法
    def staticShowTotal():  # 静态方法,可以没有参数
        print('staticmethod, Root.__total: ', Root.__total)


x = Root(3)
x.classShowTotal()  # 通过对象来调用类方法
x.staticShowTotal()  # 通过对象来调用静态方法

y = Root(5)
Root.classShowTotal()  # 通过类名调用类方法
Root.staticShowTotal()  # 通过类名调用静态方法
# Root.show()  # 试图通过类名直接调用实例方法,失败
Root.show(x)  # 可以通过这种方法来调用方法并访问实例成员

在这里插入图片描述

在这里插入图片描述

抽象方法一般在抽象类中定义,并且要求在派生类中必须重新实现,否则不允许派生类创建实例。

import abc


class Foo(metaclass=abc.ABCMeta):  # 抽象类
    def func1(self):  # 普通实例方法
        print(123)

    def func2(self):  # 普通实例方法
        print(456)

    @abc.abstractmethod  # 抽象方法
    def func3(self):
        raise Exception('must reimplement this method')


class Bar(Foo):
    def func3(self):
        print('hello world')


bar = Bar()
bar.func3()

在这里插入图片描述

  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我还记得那天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值