[英]How to type-hint “SupportsOrdering” in a function parameter?
我正在嘗試實現一個對嚴格單調遞增函數求逆的函數。 給定一個值y
和一個嚴格單調遞增的函數f
,我試圖編寫的函數將計算f_inverse(y)
並返回它。
理想情況下,這應該適用於任何定義了總排序的參數集。 所以它應該適用於int
、 float
、 tuple
等。
到目前為止,我有這個:
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
# 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
# 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.