代码之家  ›  专栏  ›  技术社区  ›  damd

记录duck类型的python参数

  •  1
  • damd  · 技术社区  · 7 年前

    我有一个功能 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,如果它很重要的话。

    1 回复  |  直到 7 年前
        1
  •  0
  •   timgeb    7 年前

    这有点毫无意义 __gt__ __eq__ 因为 object 具有这些属性。

    @提姆盖布:没想到这是实话,说得对。问题真的是关于记录这种类型的鸭子打字,所以让我们假设不是这样的?:)

    在一般情况下,我想你可以给自己写一个实现 __subclasshook__ 然后键入提示该类。

    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
    

    注意,定义 foo bar 在里面 FooAndBar 对于您的特定用途(不管怎样,子类书籍触发器)是不需要的,但是省略这些方法对我来说非常奇怪,而且可能是任何代码的阅读器。

    推荐文章