【问题标题】:Changing python type hints for subclasses更改子类的 python 类型提示
【发布时间】:2021-12-31 19:46:15
【问题描述】:

想象以下代码使用基类和 DAG 子类来处理图形:

class NodeBase:
    def some_node_func(self):
        pass

class GraphBase:
    def add(self, node: NodeBase):
        node.some_node_func()

class DirectedNode(NodeBase):
    def some_dag_func(self):
        pass

class DirectedGraph(GraphBase):
    def add(self, node: DirectedNode):
        node.some_node_func()
        node.some_dag_func()

当我尝试将此代码与 mypy 一起使用时,我收到如下错误:

error: Argument 1 of "add" is incompatible with supertype "GraphBase"; 
supertype defines the argument type as "NodeBase"  [override]

我的问题表面上与Python: how to handle type hinting in subclasses? 相似,但实际上我需要与依赖于相应DirectedNode 功能的DirectedGraph.add 函数不同的行为。

我意识到这“违反了 Liskov 替换原则”,但我不需要能够将 DirectedNode 实例添加到非 DAG 图中。

我怎样才能构造这样的东西,以便 mypy 不会抱怨?如果可能的话,我想避免仅仅禁用检查。

【问题讨论】:

    标签: python python-3.x type-hinting mypy


    【解决方案1】:

    在用于表示节点的类型上参数化GraphBase,而不是硬编码对NodeBase的引用

    from typing import Generic, TypeVar
    
    
    N = TypeVar('N', bound=NodeBase)
    
    
    class NodeBase:
        def some_node_func(self):
            pass
    
    class GraphBase(Generic[N]):
        def add(self, node: N):
            node.some_node_func()
    
    class DirectedNode(NodeBase):
        def some_dag_func(self):
            pass
    
    class DirectedGraph(GraphBase[DirectedNode]):
        def add(self, node: DirectedNode):
            node.some_node_func()
            node.some_dag_func()
    

    【讨论】:

      猜你喜欢
      • 2021-11-08
      • 2020-01-14
      • 2021-06-06
      • 2016-08-17
      • 2018-02-15
      • 2021-10-19
      • 2021-08-29
      • 2022-09-29
      • 2015-05-21
      相关资源
      最近更新 更多