python - 鸭子类型(duck typing)实践 - Python 3.7

标签 python python-3.x architecture python-3.7 duck-typing

我用 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 时,该类必须定义三个方法 flyeatdance - 否则,将出现 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/

相关文章:

python - 融化 pandas 中的分类列

javascript - 如何使用 python json 将模板渲染为 TreeView ?

ruby-on-rails - Ruby 中的存储库或网关模式

python - 计算 pandas 数据框中的匹配组合

python - 类型错误 : an integer is required (got type str) in python

python - Jupyter 小部件与 JupyterLab 扩展?

Python-删除二维列表中的列

python - map、lambda 和 append.. 为什么不起作用?

java - 需要大批量应用的设计

java - 用于开发中型 Java 应用程序的资源