123 votes

Python 3 indication de type pour None?

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

Je tente de définir une indication de type en Python dans une fonction, vous pouvez ajouter plus d'une indication de type avec quelquechose: str|bool='valeur par défaut', mais, quelles sont les indications de type pour None? :/

143voto

mbdevpl Points 1547

De votre exemple :

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

J'ai remarqué que votre cas d'utilisation est "quelque chose ou None".

Depuis la version 3.5, Python prend en charge les annotations de type via le module typing. Et dans votre cas, la manière recommandée d'annoter est d'utiliser l'indice typing.Optional[quelque chose]. Cela a exactement le sens que vous recherchez.

Par conséquent, l'indice pour another_string_or_None serait :

import typing

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

55voto

Oddthinking Points 8946

Python 3.10 prendra en charge votre notation originale souhaitée : str | None.

Source

28voto

Ollie Ford Points 1254

C'est juste None!

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

Ou du moins, cela peut l'être.

Puisque ces annotations sont sans signification pour Python au-delà de la syntaxe correcte ou incorrecte, c'est en quelque sorte à la disposition des outils.

Si vous utilisez typecheck-decorator, par exemple, alors vous devrez utiliser 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() a reçu une valeur incompatible pour nun: 0
>>> nothing(False)
typecheck.framework.InputParameterError: nothing() a reçu une valeur incompatible pour nun: False

Typecheck vous permet également d'ajouter un peu plus clairement "plus d'une indication de type avec" avec tc.any() (OU), tc.all() (ET), et bien plus encore.

Sachez que tc.none() est un prédicat de type NAND-like; pas ce que vous cherchez - sans arguments, il acceptera n'importe quel type, équivalent à tc.all() ou plus approprié tc.anything.

17voto

Hocine Abdellatif Points 183

Je sais que cette question est considérée comme répondue grâce à @mbdevpl, cependant, je voulais ajouter que type(None) est la manière d'obtenir le type réel de None, cela peut être utile par exemple dans une vérification de déclaration if comme :

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

et depuis python3.5, vous pouvez également utiliser l'opérateur Union pour plusieurs types avec None comme indiqué ici :

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

ceci équivaut à :

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

6voto

oyd11 Points 31

Selon PEP-0484: "Lorsqu'il est utilisé dans un indice de type, l'expression None est considérée comme équivalente à type(None)."

J'ai rencontré cela lors de son utilisation dans une signature d'indice de type pour @functools.singledispatch, et annoter un argument avec None fonctionne pour les décorateurs de dispatch de fonction.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X