【问题标题】:How to type hint a generic numeric type in Python?如何在 Python 中键入提示通用数字类型?
【发布时间】:2023-03-28 10:04:01
【问题描述】:

如果之前有人问过这个问题但我找不到任何相关答案,请原谅我。

考虑一个将数值类型作为输入参数的函数:

def foo(a):
    return ((a+1)*2)**4;

这适用于整数、浮点数和复数。

是否有基本类型,以便我可以进行类型提示(真实的现有类型/基类),例如:

def foo(a: numeric):
    return ((a+1)*2)**4;

另外我需要在集合类型参数中使用这个,比如:

from typing import Collection;
def foo(_in: Collection[numeric]):
    return ((_in[0]+_in[1])*2)**4;

【问题讨论】:

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


    【解决方案1】:

    PEP 3141 为数字添加了抽象基类,因此您可以使用:

    from numbers import Number
    
    def foo(a: Number) -> Number:
        ...
    

    【讨论】:

    • 小心点,因为Number 包括Complexisinstance(0+1j, Number)True
    • 对,读的太仓促了,不过和我一样还有很多人会,所以我把这个警告留在这里
    • 当我打电话给foo(1),mypy 抱怨foo has incompatible type "int"; expected "Number"。换句话说:这个答案对 mypy 用户不起作用。另请参阅此打开mypy issue
    • 顺便说一句,foo(np.int32(1)) 的情况也是如此。 mypy 引发了类似的错误:Argument 1 to "foo" has incompatible type "floating[_32Bit]"; expected "Number"。有什么建议 mypy 用户应该做什么?
    【解决方案2】:

    typing 模块中没有通用数值类型,因此您必须使用 Union 创建这样的类型:

    from typing import Union
    
    numeric = Union[int, float, complex]
    
    ...
    

    要添加对 Numpy 的数字类型集合的支持,请将 np.number 添加到该联合。

    numeric = Union[int, float, complex, np.number]
    

    【讨论】:

    • 请注意,这不适用于 numpy dtypes,但接受的答案可以。
    • @sturgemeister 我有点困惑,因为foo(np.float32(42)) 会导致mypy(我正在使用的静态类型检查器)发出Argument 1 to "foo" has incompatible type "floating[_32Bit]"; expected "Number"。您使用什么类型检查器验证了您的陈述?
    • 建议:使用numeric = Union[int, float, complex, np.number],这也适用于numpy dtypes。
    • @normanius 使用基础 python,isinstance(4, Number) and isinstance(np.ones((1,))[0], Number) 返回 true,但这似乎是一个高优先级的 mypy 问题,似乎很难解决 github.com/python/mypy/issues/3186
    • @sturgemeister 谢谢!这个问题也引起了我的注意。请注意,类型模块中的类型构造不能用于动态类型检查。 isinstance(4.2, numeric) 之类的东西会导致 TypeError。
    猜你喜欢
    • 2019-07-08
    • 2023-01-13
    • 2017-03-28
    • 2022-08-05
    • 2021-06-28
    • 2021-08-03
    • 2018-12-04
    • 2017-05-12
    相关资源
    最近更新 更多