你如何在python中验证duck-typed接口?

Dou*_*oug 8 python

class ITestType(object):
  """ Sample interface type """

  __metaclass__ = ABCMeta

  @abstractmethod
  def requiredCall(self):
    return

class TestType1(object):
  """ Valid type? """
  def requiredCall(self):
    pass

class TestType2(ITestType):
  """ Valid type """
  def requiredCall(self):
    pass

class TestType3(ITestType):
  """ Invalid type """
  pass
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,issubclass(TypeType*, ITestType)对于2返回true,对于1和3返回false.

是否有另一种方法可以使用issubclass,或者一种替代方法进行接口测试,允许1 2通过,但拒绝3?

能够使用duck typing而不是将类显式绑定到抽象类型对我来说非常有帮助,但是当duck-typed对象通过特定接口时也允许对象检查.

是的,我知道python人不喜欢接口,标准方法是"在失败时找到它并将所有内容包装在异常中",但也与我的问题完全无关.不,我不能简单地不在这个项目中使用接口.

编辑:

完善!对于发现此问题的任何其他人,以下是如何使用subclasshook的示例:

class ITestType(object):
  """ Sample interface type """

  __metaclass__ = ABCMeta

  @abstractmethod
  def requiredCall(self):
    return

  @classmethod
  def __subclasshook__(cls, C):
    required = ["requiredCall"]
    rtn = True
    for r in required:
      if not any(r in B.__dict__ for B in C.__mro__):
        rtn = NotImplemented
    return rtn
Run Code Online (Sandbox Code Playgroud)

kin*_*all 9

看看ABC模块.您可以定义一个抽象基类,该基类提供一种__subclasshook__方法,该方法根据您喜欢的任何条件定义特定类"是否是抽象基类的子类" - 例如"它有方法X,Y和Z"或其他.然后,您可以使用issubclass()isinstance()检测类和实例上的接口.