记录 Python 个鸭子类型的参数

Documenting Python params that are duck-typed

我有一个函数 foobar,它期望它的参数 baz 是实现 __gt____eq__.

的任何对象
def foobar(baz, qux):
    """
    :type baz: Any object that implements __gt__ and __eq__
    """
    if baz >= qux:
        return 'nice!'
    return 'ouch!'

对于如何记录这些类型的参数,是否有任何约定?如果重要的话,我正在使用 Python 3.5。

__gt____eq__ 有点没有意义,因为 object 有那些属性。

@timgeb: Didn't think of that to be honest, good point. The question is really about documenting this type of duck-typing, so let's pretend that's not the case? :)

在一般情况下,我想您可以自己编写一个实现 __subclasshook__ 的 ABC,然后输入 class.

from abc import ABCMeta, abstractmethod

class FooAndBar(metaclass=ABCMeta):
     @abstractmethod
     def foo(self):
         raise NotImplementedError

     @abstractmethod
     def bar(self):
         raise NotImplementedError

     @classmethod
     def __subclasshook__(cls, C):
         if cls is FooAndBar:
             has_foo = any('foo' in X.__dict__ for X in C.__mro__)
             has_bar = any('bar' in X.__dict__ for X in C.__mro__)
             if has_foo and has_bar:
                 return True
         return NotImplemented

class Foo:
    def foo(self):
        pass

class FooBar:
    def foo(self):
        pass

    def bar(self):
        pass

print(isinstance(Foo(), FooAndBar)) # False
print(issubclass(Foo, FooAndBar)) # False
print(isinstance(FooBar(), FooAndBar)) # True
print(issubclass(FooBar, FooAndBar)) # True

def func(arg: FooAndBar):
    pass

请注意,您的特定目的不需要在 FooAndBar 中定义 foobar(无论如何都会触发 subclass 钩子),但省略这些方法看起来对我来说很奇怪,可能还有任何 reader 代码。