【问题标题】:Fix multiple inheritance with generic base classes使用泛型基类修复多重继承
【发布时间】:2022-10-07 02:15:44
【问题描述】:
from typing import Generic, TypeVar, Any

R = TypeVar(\'R\')
X = TypeVar(\'X\')

class SizedIterator(Generic[X]):
    def __init__(self) -> None:
        pass

class TfmIterator(Generic[R],  SizedIterator):
    def __init__(self) -> None:
        pass

以上是https://github.com/autorope/donkeycar/blob/dev/donkeycar/pipeline/sequence.py 中代码的简化版本。

显然,该代码在 Python 3.6 和/或 3.7 中运行良好。但是,当我尝试在 Python 3.9 中运行它时,它会给出以下错误:

Traceback (most recent call last):
  File \"/Users/Shared/Personal/mycar/simple1.py\", line 10, in <module>
    class TfmIterator(Generic[R],  SizedIterator):
TypeError: Cannot create a consistent method resolution
order (MRO) for bases Generic, SizedIterator

我的问题是如何在不遇到 MRO 错误的情况下保持相同的类型提示?

    标签: python multiple-inheritance python-typing


    【解决方案1】:

    你可以试试这个:

    from typing import Generic, TypeVar, Any
    
    R = TypeVar('R')
    X = TypeVar('X')
    
    
    class SizedIterator(Generic[X]):
        def __init__(self) -> None:
            pass
    
    
    class NewIterator(Generic[R]):
        def __init__(self) -> None:
            pass
    
    
    class TfmIterator(NewIterator, SizedIterator):
        def __init__(self) -> None:
            pass
    
    

    【讨论】:

    • 谢谢!这适用于简化示例和原始代码。
    【解决方案2】:

    不需要分解出额外的基类。关键规则是:

    • Generic 必须始终是最后的基类。
    • 通常在进行菱形继承时,您可能必须将大部分 MRO 显式写入为直接父级,即使它们已经是间接父级。打印出父母的 MRO 可以帮助你弄清楚你需要写什么来获得你想要的 MRO。
    • 如果最终派生类应该不是接受泛型参数并且您需要最右边的基类不是从Generic 派生的东西,那么您将必须添加一个“虚假”基类,它实际上是Generic[T] 的别名,但使用if TYPE_CHECKING 替换自身类型分析器的空类。

    【讨论】:

      猜你喜欢
      • 2011-08-17
      • 2011-08-19
      • 2020-01-18
      • 2018-01-19
      • 1970-01-01
      • 1970-01-01
      • 2020-09-02
      • 2012-08-30
      • 1970-01-01
      相关资源
      最近更新 更多