' __subclassshook__ '继承的抽象类在Python?



我想知道如何最好地在Python的抽象类层次结构上定义__subclasshook__。假设我有一个接口,还有一个继承自这个接口的ABC。这样可以吗?

import abc
from typing import IO
class IFileHandler(metaclass=abc.ABCMeta):
def import(self) -> bytes:
raise NotImplementedError
def export(self) -> IO:
raise NotImplementedError
@classmethod
def __subclasshook__(cls, subclass):
return all((
hastattr(subclass, 'import'),
callable(getattr(subclass, 'import', None)),
hasattr(subclass, 'export'),
callable(getattr(subclass, 'export', None))
)) or NotImplemented

class FileBase(IFileHandler, metaclass=abc.ABCMeta):
def __init__(self):
... 
def import(self):
...
def export(self):
raise NotImplementedError
def another_method(self):
...
@classmethod
def __subclasshook__(cls, subclass):
if super().__subclasshook(subclass) is NotImplemented:
return NotImplemented
return all((
hasattr(subclass, '__init__'),
callable(getattr(subclass, '__init__', None)),
hasattr(subclass, 'another_method'),
callable(getattr(subclass, 'another_method', None)),
)) or NotImplemented

class ConcreteFileClass(FileBase):
def export(self):
...

是否有一种更优雅的方式来调用超类'__subclasshook__和处理其结果?我是不是完全找错了对象?任何见解将非常感激,谢谢!

您可以考虑使用abstractmethod装饰器,而不是重新发明abc的整个机制:

from abc import ABCMeta, abstractmethod
from typing import IO
class IFileHandler(metaclass=ABCMeta):
@abstractmethod
def import(self) -> bytes:
pass
@abstractmethod
def export(self) -> IO:
pass
class FileBase(IFileHandler):
@abstractmethod
def __init__(self):
pass
def import(self):
...
def export(self):
...
@abstractmethod
def another_method(self):
pass

您不需要显式地将metaclass提供给FileBase,因为继承已经处理了它。abstractmethod不允许在没有具体实现的情况下实例化子类。与其在存根方法中引发NotImplementedError,不如使用Ellipsis(...)或pass。这样,子类将能够正确地调用super().whatever而不会出现错误。

相关内容

  • 没有找到相关文章

最新更新