繁体   English   中英

如何在 Python 中使用类型提示从字面上指定特定类型(如 str(不是 str 的实例))?

[英]How do I specify literally a specific type (like str (not instance of str)) in Python with type hinting?

有没有办法可以指定一个变量应该是 Python 中的特定类型?

我知道可以指定特定类型或子类型的变量,但我怎样才能只指定该类型?

var: str  # instance of string

var: type[str] # subtype or type string

var: (literally str class)  # part in question

何时可能需要此功能的示例与联合类型有关。 例如,如果我希望传递给 function 的特定参数或 function 的返回类型的参数实际上是intstr类型,该怎么办?

def example1(arg: (Literally) int | (Literally) str):
    ...

def example2(arg) -> (Literally) int | (Literally) str:
    ...

如果要为变量指定类型,可以遵循这种做法,在将任何值放入变量之前,像这样定义变量:字符串:

x = ''

列表:

x = []

字典:

x = {}

等等...

TL; DR :你没有。

这不是类型通常的工作方式。 这就像在问“我如何才能检查某物是否只是一只熊,而不是北极熊、灰熊或任何其他熊的亚型?” 那有什么意思?

如果可以对某些内容进行子类型化,则无法按照您的要求进行操作。


请注意,我在这里谈论的是static 类型检查,而不是运行时逻辑。 当然你可以这样做:

assert type(x) is str

这将确保x属于str class 而不是子类,但有充分的理由,为什么通常不鼓励这样做:

assert isinstance(x, str)

不过,这几乎与变量的类型注释无关。

默认情况下,一个类型可以有任意数量的后代类型。 如果你想有一个自定义类型,它是final ,即子类型不应该存在,你可以使用PEP 591

from typing import final

@final
class MyStr(str):
    pass

if __name__ == '__main__':
    x: MyStr
    x = MyStr("abc")

这里与类型检查器相关的是MyStr是 final 的,这意味着当您尝试将MyStr子类化时它会给您一个错误,甚至不关心您稍后是否将该子类的值分配给x mypy为例,如果你这样做:

from typing import final


@final
class MyStr(str):
    pass


class OtherStr(MyStr):  # this is where the error occurs
    pass


if __name__ == '__main__':
    x: MyStr
    x = OtherStr("abc")  # irrelevant at this point

它根本不会抱怨最后一行。 相反,它只会说:

error: Cannot inherit from final class "MyStr"  [misc]

换句话说,当您尝试创建子类时,您对 class 所做的事情的 rest 不再重要,因为它们在定义上是无效的。


如果你真的想要,你当然可以使用 shadow str ,但这会带来一些警告:

from builtins import str as built_in_str
from typing import final


@final
class str(built_in_str):
    pass


if __name__ == '__main__':
    x: str
    x = str("abc")

我认为这是一个非常糟糕的主意。 一个原因是您不能只使用字符串文字"abc"来分配给x ,因为这会给您一个builtin.str object。 但我认为你可以想象很多其他问题。

希望这是有道理的。

暂无
暂无

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

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