【问题标题】:Type hint for a "char" / "character" type“char”/“character”类型的类型提示
【发布时间】:2022-01-23 00:40:05
【问题描述】:

“char”或“character”没有内置的原始类型,因此显然必须使用长度为 1 的字符串。但是要暗示这一点并暗示它应该被视为一个字符,如何通过类型提示来实现呢?

grade: chr = 'A'

一种方法可能是使用内置的 'chr' 函数来暗示这一点。

grade: "char" = 'A'
grade: "character" = 'A'

另一种方法可能是使用字符串类型提示来暗示这一点。

据我了解,“打字”模块中没有包含 char 类型的对象。

我搜索过的其他帖子说明了为什么某些类型提示(例如使用内置函数“chr”来表示字符)完全是错误的: Is there a PEP484 type hint for 'character'?

但是,对于应该使用什么来表示字符,没有人给出答案。使用“str”类型提示并记录它应该被视为一个字符不是我正在寻找的答案。

grade: str = 'A'  # Treat as if it were a character

我想知道在python中我应该用什么来表示“char”/“character”类型?

为了清楚起见进行编辑:我要求的是类型提示,而不是额外的计算或其他任何东西......如果我要求的是字符串长度检查或某种变体,我不会问这个问题。

【问题讨论】:

  • 如果这是字母等级,那么也许您可以使用enum 代替?它可以用于类型提示,它会限制用户添加错误的字符串。
  • @liveware 给出的成绩示例纯粹是为了举例。我一般都在问,应该用什么来表示字符。
  • 我相信你在技术上可以使用Literal["\u0000", "\u0001", "\u0002", "\u0003", …],但这会比较长。

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


【解决方案1】:

您的第一种方法是完全错误的。 chr 是内置函数,不是类型!所以你不能在类型提示中使用它。

在我看来,说它是 str 就足够了。类型提示适用于第三方,类型检查器......当 Python 不区分 char字符串,你为什么要这样做?然后,您可以实现一种逻辑,以在您的函数或方法中引发错误,或者如果该字符串包含多个项目,则无论该错误。

如果你坚持,你可以有你的自定义类型,虽然我认为它不是超级有用:

class Onechar(str):
    def __new__(cls, s):
        if len(s) > 1:
            raise ValueError("Only one character")
        return super(Onechar, cls).__new__(cls, s)

obj: Onechar
obj = "hiii"       # mypy complains
obj = Onechar("h") # fine

【讨论】:

    【解决方案2】:

    您可以使用带有注释的 str 自定义类型并覆盖 __instancecheck__

    from typing import Annotated
    
    
    class MetaChar(type):
        def __instancecheck__(self, instance: str):
            return isinstance(instance, str) and len(instance) == 1
    
    
    class Char(str, metaclass=MetaChar):
        pass
    
    
    print(isinstance('a', Char))
    print(isinstance('ab', Char))
    print(isinstance(42, Char))
    print(isinstance(1, Char))
    
    
    Chr = Annotated[str, Char]
    
    
    def foo(char: Chr) -> None:
        print(char)
    
    
    foo('a')
    

    但我认为没有任何类型检查器已经支持这一点。
    此外,这只是一个类型提示的大量代码。

    【讨论】:

      猜你喜欢
      • 2013-02-13
      • 1970-01-01
      • 2020-10-24
      • 1970-01-01
      • 2021-10-19
      • 2021-08-29
      • 2021-08-03
      • 2017-11-21
      • 2020-01-14
      相关资源
      最近更新 更多