可与mypy比较的类型 [英] Comparable types with mypy

查看:124
本文介绍了可与mypy比较的类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个通用类来表达一个值具有上下限,并强制执行这些上限.

I'm trying to create a generic class to express that a value has lower and upper bounds, and to enforce those bounds.

from typing import Any, Optional, TypeVar

T = TypeVar("T")

class Bounded(object):
    def __init__(self, minValue: T, maxValue: T) -> None:
        assert minValue <= maxValue
        self.__minValue = minValue
        self.__maxValue = maxValue

但是,mypy抱怨:

error: Unsupported left operand type for <= ("T")

显然,键入模块不允许我对此表示(尽管它看起来像将来可能会添加Comparable.

Apparently typing module doesn't allow me to express this (although it looks like adding Comparable might happen in the future).

我认为检查对象具有__eq____lt__方法就足够了(至少在我的用例中).目前有什么方法可以用Python表达此要求,以便Mypy可以理解吗?

I think it would be enough to check that object has __eq__ and __lt__ methods (for my use case at least). Is there any way to currently express this requirement in Python so that Mypy would understand it?

推荐答案

经过更多研究,我找到了一个解决方案:协议.由于它们还没有完全稳定(Python 3.6至今),因此必须从typing_extensions模块中导入它们.

After a bit more research, I found a solution: Protocols. Since they are not fully stabile (yet of Python 3.6), they have to be imported from the typing_extensions modules.

import typing
from typing import Any
from typing_extensions import Protocol
from abc import abstractmethod

C = typing.TypeVar("C", bound="Comparable")

class Comparable(Protocol):
    @abstractmethod
    def __eq__(self, other: Any) -> bool:
        pass

    @abstractmethod
    def __lt__(self: C, other: C) -> bool:
        pass

    def __gt__(self: C, other: C) -> bool:
        return (not self < other) and self != other

    def __le__(self: C, other: C) -> bool:
        return self < other or self == other

    def __ge__(self: C, other: C) -> bool:
        return (not self < other)

现在我们可以将类型定义为:

Now we can define our type as:

C = typing.TypeVar("C", bound=Comparable)

class Bounded(object):
    def __init__(self, minValue: C, maxValue: C) -> None:
        assert minValue <= maxValue
        self.__minValue = minValue
        self.__maxValue = maxValue

Mypy很高兴:

from functools import total_ordering

@total_ordering
class Test(object):
    def __init__(self, value):
        self.value = value
    def __eq__(self, other):
        return self.value == other.value
    def __lt__(self, other):
        return self.value < other.value

FBounded(Test(1), Test(10))
FBounded(1, 10)

这篇关于可与mypy比较的类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆