记录 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
中定义 foo
和 bar
(无论如何都会触发 subclass 钩子),但省略这些方法看起来对我来说很奇怪,可能还有任何 reader 代码。
我有一个函数 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
中定义 foo
和 bar
(无论如何都会触发 subclass 钩子),但省略这些方法看起来对我来说很奇怪,可能还有任何 reader 代码。