美文网首页
python笔记(十)抽象类

python笔记(十)抽象类

作者: 艺术家可达鸭 | 来源:发表于2018-12-15 19:19 被阅读3次

类也是对象,创建类对象的类被称为元类
Python 默认的元类是 type,如果类在定义时没有定义__metaclass__属性,同时其父辈类也没定义,那将使用 type 来创建这个类对象
type 的元类就是 type

# 类名,父类(可为空),绑定的成员
Test = type('Test',(),{'var':100})
test=Test()
print(type(test),type(Test),Test.var)

# 输出
# <class '__main__.Test'> <class 'type'> 100

Python中的抽象类

一种说法 java 中的接口是为了实现多继承,一个对象可以既是一种类型,也是另一种类型,而 java 只能从类中单继承,所有使用接口。Python 是可以多继承的,所以不需要接口。
但还是会有可能会用到抽象类,在【希望子类必须覆盖父类的某些成员】的时候。

创建抽象类

创建抽象类,其实就是指定类对象的元类为 ABCMeta。

from abc import ABC, ABCMeta

class ABClass():
    __metaclass__=ABCMeta

    @abc.absctractmethod
    def func(self):
        pass

# 等效于
class ABClass(metaclass=ABCMeta):
    pass

    @abc.absctractmethod
    def func(self):
        pass

# 等效于
class ABClass(ABC):
    #ABC的metaclass就是ABCMeta,所以它的子类的metaclass也是ABCMeta
    pass

    @abc.absctractmethod
    def func(self):
        pass

实现抽象类

class Implementation(ABClass):集成自抽象类,子类必须实现抽象方法,否则无法实例化;仅定义不实例化不会报错

ABClass.register(Implementation):将类注册成抽象类的虚拟子类,不强制要求实现抽象类中的抽象方法,且该抽象类不会在实体类的 MRO 列表中

抽象类可以通过实现__subclasshook__(cls,C)方法来替代 register 方法,__subclasshook__必须被定义为@classmethod

# 实现__subclasshook__的类必须是抽象类
class MyIterable(ABC):
    # __subclasshook__方法必须是类方法
    @classmethod
    def __subclasshook__(cls, C):
        if cls is MyIterable:
            if any("__iter__" in B.__dict__ for B in C.__mro__):
                return True
        return NotImplemented

issubclass() 函数在判断子类的情况下会去调用父类的__subclasshook__方法
如果该方法返回 True,表示是子类,返回 False,表示不是子类,返回 NotImplemented,将使用传统的方法来判断是否是子类,也就是判断子类在定义时是否有集成自父类。

NotImplemented 大概是一个内建模块的对象,可以直接用,就像 True,False,None 这种

相关文章

网友评论

      本文标题:python笔记(十)抽象类

      本文链接:https://www.haomeiwen.com/subject/iqaahqtx.html