简体   繁体   中英

Python 3 type hinting for None?

def foo(
        hello: str='world', bar: str=None,
        another_string_or_None: str|????=None):
    pass

I'm trying to set a type hint in Python in a function, you can add more than one type hint with something: str|bool='default value' , but, what are the type hinting for None ? :/

From your example:

def foo(
        hello: str='world', bar: str=None,
        another_string_or_None: str|????=None):
    ...

I've noticed that your use case is "something or None".

Since version 3.5, Python supports type annotations via typing module . And in your case, the recommended way of annotating is by using typing.Optional[something] hint . This has exact meaning you're looking for.

Therefore the hint for another_string_or_None would be:

import typing

def foo(
        hello: str='world', bar: str=None,
        another_string_or_None: typing.Optional[str]=None):
    ...

It's just None !

>>> def nothing(nun: None) -> None:
...     return nun
... 
>>> nothing(None)
>>> 

Or at least, it can be.

Since these annotations are meaningless to Python beyond being in/correct syntax, it's sort of up to the tools.

If you use typecheck-decorator for example, then you'll need to use type(None) :

>>> import typecheck as tc
>>>
>>> @tc.typecheck
>>> def nothing(nun: type(None)) -> type(None):
...     return nun
... 
>>> nothing(None)
>>> nothing(0)
typecheck.framework.InputParameterError: nothing() has got an incompatible value for nun: 0
>>> nothing(False)
typecheck.framework.InputParameterError: nothing() has got an incompatible value for nun: False

Typecheck also allows you to somewhat more clearly "add more than one type hint with" with tc.any() (OR), tc.all() (AND), and far more besides.

Beware that tc.none() is a NAND-like predicate; not what you are looking for - with no arguments it will accept any type, equivalent to tc.all() or the more apt tc.anything .

Python 3.10 will support your original desired notation: str | None str | None .

Source

I know this question is considered answered thanks to @mbdevpl, however, I've wanted to add that type(None) is how you get the actual for None type, this can be useful for example in an if statement check like:

if isinstance(x_var, type(None)):
    pass

and since python3.5 , you can also use do Union of a bunch of types with None as shown here:

x_var: typing.Union[str, None]
y_var: typing.Union[Dict, List, None]

this is equivalent to:

x_var: typing.Optional[str]
y_var: typing.Optional[typing.Union[Dict, List]]

According to PEP-0484 : "When used in a type hint , the expression None is considered equivalent to type(None) ."

I came around it when using in a type-hint signature for @functools.singledispatch , and annotating an argument with None does work for the function dispatch decorators.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM