Как проверить, является ли какой-либо аргумент в Union [...] None в python? - PullRequest
3 голосов
/ 01 октября 2019

Я хочу отфильтровать код, где любой аргумент в Union [..] равен None. Каков наилучший способ определения аргументов None?

Я знаю, что порядок аргументов не имеет значения в Union [] (от ввода import Union), но как мне выполнить общую проверку (возможно, функцию) для обнаруженияНет аргументов.

from typing import Union
Union[T, None]

1 Ответ

3 голосов
/ 01 октября 2019

Вы можете использовать свойство функции __annotations__:

def my_func(a: Union[int, None], b: int, c: str):
    print(a,b,c)

print(my_func.__annotations__) # {'a': typing.Union[int, NoneType], 'b': <class 'int'>, 'c': <class 'str'>}

Теперь мы можем сделать что-то для программной проверки:

from typing import _GenericAlias

def check_if_func_accepts_none(func):
    for key in func.__annotations__:
        if isinstance(func.__annotations__[key], type(None)):
            return True
        elif isinstance(func.__annotations__[key], _GenericAlias) and type(None) in func.__annotations__[key].__args__:
            return True
    return False

Примеры:

>>> def b(a:int, b:None):
...     print('hi')
...
>>> def c(x:Union[None,str], y:int):
...     print('hi')
...
>>> def d(z: int, s:str):
...     print('hi')
...
>>> check_if_func_accepts_none(b)
True
>>> check_if_func_accepts_none(c)
True
>>> check_if_func_accepts_none(d)
False
>>>

РЕДАКТИРОВАТЬ: Чтобы ответить на ваш комментарий, чтобы проверить Union объектов непосредственно:

type(None) in obj.__args__

Это вернет True, если None есть и False в противном случае (при условии, что obj являетсяUnion)

...