抽象基类register方法在Python中实际做什么?

r1zk6ea1  于 2022-11-26  发布在  Python
关注(0)|答案(2)|浏览(97)

我对ABC寄存器方法感到困惑。
下面的代码:

import io
from abc import ABCMeta, abstractmethod

class IStream(metaclass=ABCMeta):
    @abstractmethod
    def read(self, maxbytes=-1):
        pass
    @abstractmethod
    def write(self, data):
        pass

IStream.register(io.IOBase)

f = open('foo.txt')

isinstance(f, Istream) # returns true

当你注册io.IOBase的时候,到底发生了什么?你是说IOBase类只能有Istream ABC类定义的方法吗?ABC注册其他类的好处是什么?

bvpmtnay

bvpmtnay1#

它只是让issubclass(io.IOBase, IStream)返回True(这意味着io.IOBase的一个示例是IStream的一个示例),由注册该类的程序员来确保io.IOBase实际上 * 符合 * IStream定义的API。
原因是让你定义一个IStream形式的接口,并让你指出一个可能实际上没有从IStream继承的类满足这个接口。本质上,它只是形式化的duck类型。

toe95027

toe950272#

例如,我们可以替换**Cat扩展Animal类**如下:

from abc import ABC, abstractmethod

class Animal(ABC):
    @abstractmethod
    def sound(self):
        pass

# ↓↓↓ Here ↓↓↓

class Cat(Animal):
    def sound(self):
        print("Meow!!")

# ↑↑↑ Here ↑↑↑

print(issubclass(Cat, Animal))

以下代码具有register()

from abc import ABC, abstractmethod

class Animal(ABC):
    @abstractmethod
    def sound(self):
        pass

# ↓↓↓ Here ↓↓↓

class Cat:
    def sound(self):
        print("Meow!!")
        
Animal.register(Cat)

# ↑↑↑ Here ↑↑↑

print(issubclass(Cat, Animal))

然后,上面的两个代码都输出以下相同的结果,显示**Cat classAnimal class**的子类:

True

相关问题