小能豆

专门化正则表达式类型 re.Pattern

py

re.Pattern将的类型专门化为re.Pattern[bytes]mypy可以正确检测类型错误:

import re
REGEX: re.Pattern[bytes] = re.compile(b"\xab.{2}")
def check(pattern: str) -> bool:
    if str == "xyz":
        return REGEX.fullmatch(pattern) is not None
    return True
print(check("abcd"))

检测到类型不匹配:

$ mypy ~/main.py 
/home/oren/main.py:5: error: Argument 1 to "fullmatch" of "Pattern" has incompatible type "str"; expected "bytes"
Found 1 error in 1 file (checked 1 source file)

然而,当我尝试实际运行代码时,我收到一条奇怪的(?)消息:

$ python ~/main.py
Traceback (most recent call last):
  File "/home/oren/main.py", line 2, in <module>
    REGEX: re.Pattern[bytes] = re.compile(b"\xab.{2}")
TypeError: 'type' object is not subscriptable

类型注释怎么会困扰 Python?


阅读 16

收藏
2024-11-15

共1个答案

小能豆

您遇到的问题是因为re.Pattern在 Python 3.9 之前的版本中,类型本身不可“下标”。在早期版本(例如 3.8 及以下版本)中,re.Pattern不是通用的,无法使用类似 的类型进行参数化re.Pattern[bytes]

以下是具体情况:

  1. Mypy 类型注释:在mypy类型检查器中,您可以使用re.Pattern[bytes]来指定正则表达式模式需要一个字节对象(即,一个bytes字符串,而不是str),并且在您尝试传递一个而不是mypy时正确检测类型不匹配。str``bytes
  2. Python 的re模块(Python 3.9 之前):早期版本的 Python 的标准re.Pattern类型不是参数化类型,因此尝试将其用作re.Pattern[bytes]泛型类型会导致 Python 解释器引发TypeError,表示'type' object is not subscriptable

修复

  1. 升级到 Python 3.9+:如果您使用的是 Python 3.9 或更高版本,re.Pattern则已将其设为通用类型,因此您可以正确使用re.Pattern[bytes]注释而不会出现任何问题。请确保您至少使用 Python 3.9 以避免此错误。

  2. 适用于 Python 3.8 或更早版本的解决方法:在 Python 3.9 之前的版本中,您仍然可以使用,但不带类型参数。要正确re.Pattern注释的类型,您应该只使用并依赖进行类型检查:REGEX``re.Pattern``mypy

```
import re

# No subscript in Python 3.8 or earlier
REGEX: re.Pattern = re.compile(b”\xab.{2}”)

def check(pattern: str) -> bool:
if pattern == “xyz”:
return REGEX.fullmatch(pattern.encode()) is not None # encode pattern to bytes
return True

print(check(“abcd”))
```

在这种情况下,您不会bytes直接在 中使用 进行注释re.Pattern,但要确保在使用 时REGEX,模式bytes与 而不是正确匹配str

2024-11-15