python 如何获取一个 UnionType 的子成员?

作者站长头像
站长
· 阅读数 12

python 如何获取一个 UnionType 的子成员?python 如何判断指定类型是否在 UnionType 中?


我有一个需求,就是判断一个 func 的 name 参数的 typing hints 是不是包含了 str,如果包含了就返回 True,否则返回 False

比如

  • def func(name:int):pass 就是 False,因为 name 的 typing hints 是 int
  • def func(name:int|None):pass 就是 False,因为 name 的 typing hints 不包含 str
  • def func(name:float):pass 就是 False,因为 name 的 typing hints 不包含 str
  • def func(name:str|None):pass 就是 True,因为 name 的 typing hints 包含 str
  • def func(name:str):pass 就是 True,因为 name 的 typing hints 包含 str

我遇到的问题是,当 typing hints 只有一个 type 的时候,我可以直接通过 from inspect import signature 的 parameter.annotation 来判断,但是当 typing hints 使用了 | 的时候,parameter.annotation 的 type 就是 types.UnionType 了,而这个 types.UnionType 貌似没有办法通过 in 等操作符,来判断 str 是不是在这个 types.UnionType 中;types.UnionType 也不能用 for 迭代已获取其中的子元素!

例如下面的代码:

from typing import Union, Callable
from types import UnionType
from inspect import signature
from loguru import logger


def check_func_args_hints(func: Callable)->bool:
    typed_signature = signature(func).parameters.items()

    # 我需要获取这个 func 函数的 name 参数,是否支持 str 这个 typing_hint

    for index, (parameter_name, parameter) in enumerate(typed_signature):
        if parameter_name!='name':
            continue


        logger.debug(parameter.annotation)
        logger.debug(type(parameter.annotation))
        logger.debug(f'----------------')
    


def get_score(name: str | None = None) -> float | None:
    pass


check_func_args_hints(get_score)

输出

2022-10-04 19:06:26.472 | DEBUG    | __main__:check_func_args_hints:17 - str | None
2022-10-04 19:06:26.472 | DEBUG    | __main__:check_func_args_hints:18 - <class 'types.UnionType'>
2022-10-04 19:06:26.472 | DEBUG    | __main__:check_func_args_hints:19 - ----------------

我该怎么办?

回复
1个回答
avatar
test
2024-07-18
  1. typing.get_args 可以得到 generic type 的“参数”:

str in typing.get_args(parameter.annotation)

  1. 直接使用 isinstance 判断一个字符串(比如"")是否是这个类型的:

isinstance("", parameter.annotation)

回复
likes
适合作为回答的
  • 经过验证的有效解决办法
  • 自己的经验指引,对解决问题有帮助
  • 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
  • 询问内容细节或回复楼层
  • 与题目无关的内容
  • “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容