Python类的约束以及super()剖析

枫铃4年前 (2021-07-09)Python233

1.类的约束
第一版:

class WechatPay:

    def pay(self):
        print("微信支付")

class AliPay:

    def pay(self):
        print("支付宝支付")

class QQpay:

    def fuqian(self):
        print("QQ支付")

wei = WechatPay()
ali = AliPay()
qq = QQpay()

wei.pay()
ali.pay()
qq.fuqian()

# 当统一接口时
def pay(object):
    object().pay()       # QQ支付无法实现归一化

第二版:

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:857662006 寻找有志同道合的小伙伴,
互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
class PayClass:

    def pay(self):
        pass

class WechatPay(PayClass):

    def pay(self):
        print("微信支付")

class AliPay(PayClass):

    def pay(self):
        print("支付宝支付")

class QQpay(PayClass):

    def fuqian(self):
        print("QQ支付")

def pay(object):

    object().pay()

pay(WechatPay)
pay(QQpay)        # QQpay会执行父类的pay方法但是无法完成支付

(1)对类的约束有两种:
<1> 提取⽗类. 然后在⽗类中定义好⽅法. 在这个⽅法中什么都不⽤⼲. 就抛⼀个异常就可以了. 这样所有的⼦类都必须重写这个⽅法. 否则. 访问的时候就会报错.
<2> 使⽤元类来描述⽗类. 在元类中给出⼀个抽象⽅法. 这样⼦类就不得不给出抽象⽅法的具体实现. 也可以起到约束的效果.
第三版:

#  方式一:  (推荐并且常用的方式)
# raise   主动抛出异常(主动报错)
class PayClass:
    def pay(self):
        raise Exception("你子类必须要写一个pay方法")

class WechatPay(PayClass):

    def pay(self):
        print("微信支付")

class AliPay(PayClass):

    def pay(self):
        print("支付宝支付")

class QQpay(PayClass):

    def fuqian(self):
        print("QQ支付")

def pay(object):
    object().pay()

pay(WechatPay)
pay(QQpay)     # QQpay类中没有pay方法,raise就会主动抛出异常(主动报错)



# 方法二
#  抽象类,接口类: 制定一些规则
from abc import ABCMeta,abstractmethod   # 抽象类,接口类
class PayClass(metaclass=ABCMeta):      # 元类
    @abstractmethod
    def pay(self):
        raise Exception("你子类必须要写一个pay方法")

class WechatPay(PayClass):

    def pay(self):
        print("微信支付")

class AliPay(PayClass):

    def pay(self):
        print("支付宝支付")

class QQpay(PayClass):

   def fuqian(self):
        print("QQ支付")
        
def pay(object):
    object().pay()

pay(WechatPay)
pay(AliPay)
pay(QQpay)     # QQpay类中没有pay方法,就会与指定的规则不符导致报错

总结:
约束. 其实就是⽗类对⼦类进⾏约束. ⼦类必须要写xxx⽅法. 在python中约束的⽅式和⽅法有两种:

  • 使⽤抽象类和抽象⽅法, 由于该⽅案来源是java和c#. 所以使⽤频率还是很少的

  • 使⽤⼈为抛出异常的⽅案. 并且尽量抛出的是NotImplementError. 这样比较专业, ⽽且错误比较明确.(推荐)

2.super 剖析
super是严格按照类的继承顺序执行

class A:
    def f1(self):
        print('in A')

class Foo(A):
    def f1(self):
        super().f1()
        print('in Foo')

class Bar(A):
    def f1(self):
        print('in Bar')

class Info(Foo,Bar):
    def f1(self):
        # super里的类名是指定查找mro中类名的下一个类, self是指定查找时使用的mro顺序
        super(Info,self).f1()   # Foo() 对象的内存地址  # super(子类名,子类的mro列表)
        print('in Info f1')


aa = Info()  # 对象的内存地址
aa.f1()

# Info       [Info', Foo', Bar', A', 'object']

a = Foo()
b = a
print(a)
print(b)

print(Info.mro())
obj = Info()
obj.f1()

相关文章

利用python同步windows和linux文件

写python脚本的初衷,每次在windows编辑完文件后,想同步到linux上去,只能够登录服务器,...

爬虫基本原理

爬虫基本原理 一、爬虫是什么? 百度百科和维基百科对网络爬虫的定义:简单来说爬虫就是抓取目标网站内容的工具,一般是根据定义的行...

Django 函数和方法的区别

函数和方法的区别 1、函数要手动传self,方法不用传 2、如果是一个函数,用类名去调用,如果是一个方法...

Django 知识补漏单例模式

单例模式:(说白了就是)创建一个类的实例。在 Python 中,我们可以用多种方法来实现单例模式&#x...

Django基础知识MTV

Django简介 Django是使用Python编写的一个开源Web框架。可以用它来快速搭建一个高性能的网站。 Django也是一个MVC框架。但是在Dj...

Python mysql 索引原理与慢查询优化

一 介绍 为何要有索引? 一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。