【问题标题】:Change Type Hint of Inherited Method更改继承方法的类型提示
【发布时间】:2022-01-20 20:57:18
【问题描述】:

问题

假设您有一个类A 和一个子类B。如果A 的方法foo 返回与B 不同的变量类型,您将如何在不重新定义/覆盖方法本身的情况下覆盖该方法的类型提示?

现实例子

class RGB:
    def __init__(self, color: Union[tuple[int, int, int], tuple[int, int, int, int]]) -> None:
        self.__color: Union[tuple[int, int, int], tuple[int, int, int, int]] = color
        return

    def __eq__(self, other: Union[RGB, RGBA]) -> bool:
        return isinstance(other, RGB) and self.__color == other.color

    @property
    def color(self) -> tuple[int, int, int]:
        return self.__color


class RGBA(RGB):
    def __init__(self, color: tuple[int, int, int, int]) -> None:
        super().__init__(color)
        return

    @property
    def color(self) -> tuple[int, int, int, int]:
        return self.__color

如您所见,color 属性会根据给定颜色是否具有 alpha 值而有所不同。但我不想/不需要重新定义/覆盖 color 属性方法,功能不会改变。如何在不覆盖方法的情况下为 color 属性定义返回类型提示?

理想情况下,RGBA 类将只包含 __init__ 函数。

【问题讨论】:

  • 这打破了里氏替换原则;你根本不应该改变color 的类型。 RGBA 规范不是一种 RGB 规范。不要使用继承。
  • 没听说过这个原理,谢谢提供信息。
  • 我会使用两个单独的类。 反转继承是很诱人的,让 RGB 规范成为一种特殊的 RGBA 规范,始终将 alpha 通道设置为 0 或 None 或其他一些固定值,但即使这样也很粗略。从 RGBA 到 RGB 的转换很简单(去掉 alpha 通道),但相反的方向需要您指定任意 alpha 值。

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


【解决方案1】:

您可以有一个通用的Color 类,它作为RGBRGBA 的共同父类,由用于表示它们的元组类型参数化。例如,

from typing import Generic, TypeVar


C = TypeVar('C')


class Color(Generic[C]):
    def __init__(self, c: C):
        self.__color = c

    @property
    def color(self) -> C:
        return self.__color


class RGB(Color[tuple[int,int,int]]):
    pass


class RGBA(Color[tuple[int,int,int,int]]):
    pass

这只是一个开始;当您向类添加更多详细信息时,您可能会遇到其他问题。

【讨论】:

  • 如果我理解正确,这会将 TypeVarC 设置为各个类 RGB 类所需的 tuple
  • 正确。如果不出意外,这至少使子类彼此独立,简化了它们的每个定义,而不必担心其他的。
  • 这很有趣。不幸的是,我的 IDE 似乎没有比TypeVarC 更深入地理解,但这个答案合乎逻辑,谢谢!
猜你喜欢
  • 2023-03-30
  • 1970-01-01
  • 2018-08-24
  • 1970-01-01
  • 2013-12-04
  • 1970-01-01
  • 1970-01-01
  • 2014-11-24
  • 2015-10-18
相关资源
最近更新 更多