gpt4 book ai didi

python - 如何将 "value"属性强类型为 str 或自定义类型?

转载 作者:行者123 更新时间:2023-12-04 17:18:05 25 4
gpt4 key购买 nike

在严格类型检查模式下使用 Pylance (ms-python.vscode-pylance) VS Code 扩展时,我的自定义 Enum 值出现以下代码的类型错误:

def println_ctrl_sequence(message: str, ctrlSequence: Union[ANSICtrlSequence, str]):
"""
This function is use with terminals to print the message
with colors specified by a, ANSI control sequence that
can be either a str or a console.ANSICtrlSequence object.
"""
if type(ctrlSequence) == ANSICtrlSequence:
ctrlSequenceStr: str = ctrlSequence.value
else:
ctrlSequenceStr = ctrlSequence

print("%s%s%s" % (
ctrlSequenceStr,
message,
ANSICtrlSequence.RESET.value
))
ctrlSequenceStr: str = ctrlSequence.value 上检测到类型错误线路自 ctrlSequence.value被检测为类型 Any | Unknown .所以我的目标是强输入 value我扩展的属性 Enum :
# python enum : https://docs.python.org/3/library/enum.html 
from enum import Enum

class ANSICtrlSequence(Enum):

# basic control sequences
RESET = "\033[m"

# full control sequences
PASSED = "\033[1;4;38;5;76m"
FAILED = "\033[1;5;38;5;197m"
我尝试过诸如做 ANSICtrlSequence(str, Enum) 之类的事情。如指定 here in "String-based enum in Python" Q&A没有成功。
我读过课 enum.pyi我可以理解为什么值的类型是这样的:
class Enum(metaclass=EnumMeta):
name: str
value: Any
...
我找不到一种方法将我的 value 属性输入为 str 在 documentation 中的任何位置或在 StackOverflow .那么有可能吗?有没有办法 覆盖继承属性的类型 ?或者我是否需要使用例如 IntEnum 的等效项来扩展 Enum 类,例如可以是 StrEnum ?也许我需要编写自己的强类型 Enum 类?有什么我错过的吗?

最佳答案

看来问题不完全来自Enum.value但从包括 str作为 ctrlSequence 的可能类型. Pylance 似乎会检查 Union 中是否包含所有类型有一个 .value属性,以及 str ,当然,它没有.value所以 Pylance 不知道期望什么类型(即“未知”)。
我们可以在不使用 Enum 的情况下重现类似的“未知”错误。 :

x = 5
print(x.value)
similar error without enum
在您的情况下,请遵循 string-based enum解决方案并继承自 str定义您的 Enum 时仍然是必要的,因为这向类型检查器(这里是 Pylance)表明您的 Enum .valuestr -类型。
所以,你绝对需要这个来强输入你的枚举:
class ANSICtrlSequence(str, Enum):
RESET = "\033[m"
PASSED = "\033[1;4;38;5;76m"
FAILED = "\033[1;5;38;5;197m"
但是,它仍然显示为

Type of "value" is partially unknown
^ Type of "value" is "Any | Unknown*"


因为在 Union[ANSICtrlSequence, str].value的类型为 ANSICtrlSequenceAny.value的类型为 str是未知的。此问题与 str当您将联合的顺序颠倒为 Union[str, ANSICtrlSequence] 时很明显,然后变成

 Type of "value" is "Unknown | Any"


...表明“未知”与 str 相关联.基本上,我的观点是 你不应该专注于输入 .value枚举的属性,因为问题在于包含 str .如果您删除 Union,该错误实际上会消失。只需使用 ANSICtrlSequence :
class ANSICtrlSequence(str, Enum):
RESET = "\033[m"
PASSED = "\033[1;4;38;5;76m"
FAILED = "\033[1;5;38;5;197m"

def println_ctrl_sequence(message: str, ctrlSequence: ANSICtrlSequence):
# Pylance does not complain here
ctrlSequenceStr: str = ctrlSequence.value
...这表明您的 Enum 没有任何问题首先。
但我明白为什么代码中有一个 Union 。不幸的是,Pylance 没有。它不明白当代码到达 ctrlSequence.value 时代码已经检查了 ctrlSequenceEnum .
有趣的是,有效的是改变检查类型的方式。而不是 type(obj) , 使用 isinstance(obj, classinfo) :
class ANSICtrlSequence(str, Enum):
RESET = "\033[m"
PASSED = "\033[1;4;38;5;76m"
FAILED = "\033[1;5;38;5;197m"

def println_ctrl_sequence(message: str, ctrlSequence: Union[ANSICtrlSequence, str]):
if isinstance(ctrlSequence, ANSICtrlSequence):
ctrlSequenceStr: str = ctrlSequence.value
else:
ctrlSequenceStr = ctrlSequence
no errors with isinstance
...满足 Pylance 并修复错误:)
我希望这不是“它适用于我的环境”的情况,但我几乎总是使用 isinstance而不是 type在检查对象的类型时,我的代码中的 Enums 或 Unions with Enums 没有出现任何 Pylance 错误。我不知道 Pylance 是如何工作的,但这里有一个关于该主题的相关问答: What are the differences between type() and isinstance()?
如果你真的需要使用 type(ctrlSequence) ,那么你可以使用 typing.cast , 哪个:

Cast a value to a type.

This returns the value unchanged. To the type checker this signals that the return value has the designated type, but at runtime we intentionally don’t check anything (we want this to be as fast as possible).

from typing import Union, cast

class ANSICtrlSequence(str, Enum):
RESET = "\033[m"
PASSED = "\033[1;4;38;5;76m"
FAILED = "\033[1;5;38;5;197m"

def println_ctrl_sequence(message: str, ctrlSequence: Union[ANSICtrlSequence, str]):
if type(ctrlSequence) == ANSICtrlSequence:
ctrlSequence = cast(ANSICtrlSequence, ctrlSequence)
ctrlSequenceStr: str = ctrlSequence.value
else:
ctrlSequenceStr = ctrlSequence
no errors by using cast
...这再次满足 Pylance 并修复了错误:) cast强制执行 ctrlSequence 的类型检查器(这里是 Pylance)是您的 Enum 类型,而 .value确实是一个字符串。

关于python - 如何将 "value"属性强类型为 str 或自定义类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68032592/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com