我用 Python 编写了一个库,我希望代码能够 self 解释,但我发现很难使用鸭子类型(duck typing)。
假设我有一个接受参数 A 的类。 该参数必须实现飞行、饮食和舞蹈方法。 另一个程序员甚至我自己如何在不读取整个类的代码或辅助函数的代码的情况下轻松知道参数必须实现什么行为?
现在,我在每个类之上定义了一个接口(interface),其中包含详细的 bahvior - 用于 self 解释的代码。
有什么想法吗?更好的灵魂?
最佳答案
你的例子听起来像 abstract class 。您可以定义一个抽象类,并为该参数添加类型注释或显式检查其类型:
from abc import ABC, abstractmethod
class MyABC(ABC):
@abstractmethod
def fly(self):
pass
@abstractmethod
def eat(self):
pass
@abstractmethod
def dance(self):
pass
对于你的方法:
def test(param: MyABC):
if not isinstance(param, MyABC):
raise Exception("param must inherit MyABC.")
这是有效的,因为当将 param
传递给 test
方法时,它必须继承 MyABC
- 并且为了继承 MyABC
时,该类必须定义三个方法 fly
、eat
、dance
- 否则,将出现 TypeError
尝试实例化它时引发。
编辑:
如果您希望子类不直接继承,但仍“算作”MyABC
子类,则可以使用 __subclasshook__
:
from abc import ABC, abstractmethod
class MyABC(ABC):
@abstractmethod
def fly(self):
pass
@abstractmethod
def eat(self):
pass
@abstractmethod
def dance(self):
pass
@classmethod
def __subclasshook__(cls, C):
if any("fly" in B.__dict__ for B in C.__mro__):
# add checks for dance and eat...
return True
return NotImplemented
现在,每个实现 fly
方法的类(或继承实现该方法的类)都会在以下条件下返回 True
:
isinstance(CLASS, MyABC)
来自流利的Python:
The subclasshook adds some duck typing DNA to the whole goose typing proposition. You can have formal interface definitions with ABCs, you can make isinstance checks everywhere, and still have a completely unrelated class play along just because it implements a certain method (or because it does whatever it takes to convince a subclasshook to vouch for it). Of course, this only works for ABCs that do pro‐ vide a subclasshook.
关于python - 鸭子类型(duck typing)实践 - Python 3.7,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57542482/