为了账号安全,请及时绑定邮箱和手机立即绑定

我可以使用来自另一个函数的输入信息作为 Python 中的返回类型吗?

我可以使用来自另一个函数的输入信息作为 Python 中的返回类型吗?

陪伴而非守候 2022-07-12 17:49:24
在以下示例中,如何正确注释sum_two函数的返回类型?from typing import Any, TypeVarT = TypeVar('T')S = TypeVar('S')def sum_two(first: T, second: S):    return first + second假设__add__运算符为将传递给此函数的所有可能参数正确注释,是否有某种方法可以将返回类型表示为调用类型和__add__对象的返回类型?TS我想避免使用打字的overload装饰器来识别所有可能的情况,因为可能有几十种情况。
查看完整描述

1 回答

?
弑天下

TA贡献1818条经验 获得超8个赞

理论上,您可以通过制作一个通用协议来完成他的一部分first,它可以让您“捕获” __add__. 例如:


# If you are using Python 3.7 or earlier, you'll need to pip-install

# the typing_extensions module and import Protocol from there.

from typing import TypeVar, Protocol, Generic


TOther = TypeVar('TOther', contravariant=True)

TSum = TypeVar('TSum', covariant=True)


class SupportsAdd(Protocol, Generic[TOther, TSum]):

    def __add__(self, other: TOther) -> TSum: ...


然后,您可以执行以下操作:


S = TypeVar('S')

R = TypeVar('R')


# Due to how we defined the protocol, R will correspond to the

# return type of `__add__`.

def sum_two(first: SupportsAdd[S, R], second: S) -> R:

    return first + second


# Type checks

reveal_type(sum_two("foo", "bar"))  # Revealed type is str

reveal_type(sum_two(1, 2))          # Revealed type is int

reveal_type(sum_two(1.0, 2))        # Revealed type is float


# Does not type check, since float's __radd__ is ignored

sum_two(1, 2.0)


class Custom:

    def __add__(self, x: int) -> int:

        return x


# Type checks

reveal_type(sum_two(Custom(), 3))  # Revealed type is int


# Does not type check

reveal_type(sum_two(Custom(), "bad"))

但是,这种方法确实有一些限制:

  1. 它不处理__add__在“第一”中没有匹配但__radd__在“第二”中有匹配的情况。

  2. 如果你修改自定义,你可能会得到一些奇怪的结果,所以这__add__是一个重载。我认为至少 mypy 目前有一个错误,它不知道如何正确处理涉及子类型和重载的复杂情况。


查看完整回答
反对 回复 2022-07-12
  • 1 回答
  • 0 关注
  • 138 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号