如何在Python中检查对象是否可用作类型注释?

2024-06-02 06:23:11 发布

您现在位置:Python中文网/ 问答频道 /正文

根据PEP484,允许将以下内容用作类型注释

v: int # built-in class
v: MyABC # abstract base class
v: types.FunctionType # types defined in `types` module
v: MyClass # user-defined class
v: None # None is a value, but ok
v: typing.List[int] # Generics

我想检查variable是否可以用作类型批注:

def is_annotation(v: Any) -> bool:
   # How to implement?

is_annotation(int)                == True
is_annotation(1)                  == False
is_annotation(types.FunctionType) == True
is_annotation(None)               == True

Tags: inabstractnonetrue类型isannotationclass
1条回答
网友
1楼 · 发布于 2024-06-02 06:23:11

键入有一个内部函数(_type_check),用于确定批注是否有效。编写函数时,如果批注无效,则会引发类型错误。我们可以通过调用_type_check并在引发异常时返回false的函数惰性地利用此漏洞

import typing, types
from typing import Any

def is_annotation(v: Any) -> bool:
    try:
        typing._type_check(v, 'Not valid')
        return True
    except TypeError:
        return False

或者,我们可以重写函数,将其行为从引发异常更改为返回False

def is_annotation(v: Any) -> bool:
    if v is None:
        return True
    if isinstance(v, str):
        return True
    if (isinstance(v, typing._GenericAlias) and
            v.__origin__ in (typing.Generic, typing.Protocol)):
        return False
    if (isinstance(v, typing._SpecialForm) and v not in (typing.Any, typing.NoReturn) or
            v in (typing.Generic, typing.Protocol)):
        return False
    if isinstance(v, (type, typing.TypeVar, typing.ForwardRef)):
        return True
    if not callable(v):
        return False
    return True


print(is_annotation(int))
print(is_annotation(1))
print(is_annotation(types.FunctionType))
print(is_annotation(10.0))
print(is_annotation(typing.List))
print(is_annotation('str'))
print(is_annotation(None))

相关问题 更多 >