繁体   English   中英

如何在函数参数中键入提示“SupportsOrdering”?

[英]How to type-hint “SupportsOrdering” in a function parameter?

我正在尝试实现一个对严格单调递增函数求逆的函数。 给定一个值y和一个严格单调递增的函数f ,我试图编写的函数将计算f_inverse(y)并返回它。

理想情况下,这应该适用于任何定义了总排序的参数集。 所以它应该适用于intfloattuple等。

到目前为止,我有这个:

def invert_strictly_monotonic_function(y: Any, f: Callable[[Any], Any]) -> Any:
    pass

我想用"SupportsOrdering"类的东西替换Any - 这会告诉我我可以依赖这个函数中的__eq____lt__方法。

但是,当然,在typing模块中不存在SupportsOrdering

那么,我该如何进行类型提示呢? 我需要为此定义自己的协议类型吗? 我将如何使用@total_ordering类的@total_ordering

由于打字模块不提供可比较的类型,我认为另一种方法是使用types.protocol作为基类(用于结构子类型)定义我们自己的自定义类型,需要比较器方法,例如__lt____eq__与用户-定义SupportsOrdering ,灵感来自这些预定义协议列表,例如typing.SupportsRound

用户定义的可比较类型:

from __future__ import annotations

from abc import abstractmethod
from typing import Protocol, runtime_checkable, TypeVar


@runtime_checkable
class Comparable(Protocol):
    @abstractmethod
    def __lt__(self: SupportsOrdering, other: SupportsOrdering) -> bool:
        pass

    @abstractmethod
    def __eq__(self: SupportsOrdering, other: object) -> bool:
        pass


SupportsOrdering = TypeVar("SupportsOrdering", bound=Comparable)

测试可比类型的功能:

class MyNonComparableClass:
    def __init__(self, data):
        self.data = data


class MyComparableClass:
    def __init__(self, data):
        self.data = data

    def __lt__(self: MyComparableClass, other: MyComparableClass) -> bool:
        return self.data < other.data

    def __eq__(self: MyComparableClass, other: object) -> bool:
        if not isinstance(other, MyComparableClass):
            return NotImplemented
        return self.data == other.data


def func(value: SupportsOrdering) -> SupportsOrdering:
    return value

测试 1:可比类型

# Comparable built-ins
func(True)
func(1)
func(1.2)
func("a")
func("abc")
func([1, 2, 3])  # Sequence objects typically may be compared https://docs.python.org/3/tutorial/datastructures.html#comparing-sequences-and-other-types
func((1, 2, 3))
func({1, 2, 3})

# Comparable user-defined class
func(MyComparableClass(1))

输出:

$ mypy script.py  # Install mypy via <python3 -m pip install mypy>
Success: no issues found in 1 source file

测试 2:不可比较的类型

# Non-comparable built-ins
func({"1": "1"})  # Order comparisons (‘<’, ‘<=’, ‘>=’, ‘>’) raise TypeError. https://docs.python.org/3/library/stdtypes.html#mapping-types-dict

# Non-comparable user-defined class
func(MyNonComparableClass(1))

输出:

$ mypy script.py  # Install mypy via <python3 -m pip install mypy>
script.py:57: error: Value of type variable "SupportsOrdering" of "func" cannot be "Dict[str, str]"
script.py:60: error: Value of type variable "SupportsOrdering" of "func" cannot be "MyNonComparableClass"

参考:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM