Dans la nouvelle version Python 3.8 il y a une nouvelle annotation de type typing.TypedDict
. Sa documentation mentionne que
Les informations de type pour l'introspection sont accessibles via
Point2D.__annotations__
etPoint2D.__total__
. [....]
Tandis que __annotations__
est bien connu, ayant été introduit dans PEP 3107 , je ne trouve aucune information sur __total__
. Quelqu'un pourrait-il expliquer sa signification et si possible un lien vers des sources faisant autorité?
Je suppose que le champ __total__
Signifie si les instances doivent être complètes (par défaut) ou non (tous les champs facultatifs). J'ai commencé ma recherche à PEP 589 , qui a introduit TypedDict
et décrit la totalité comme telle. Il a utilisé un argument total
, qu'il serait judicieux de renommer dunder-style pour la syntaxe class
. Cependant, je n'ai pas trouvé quand un tel changement de nom a eu lieu.
En examinant MyPy, qui est le vérificateur de type réel qui se soucie de ces annotations, il y a documentation similaire sur TypedDict
et la totalité , mais encore une fois aucune référence à la syntaxe dunder. Creuser dans son implémentation a conduit à plus de confusion, car TypedDictType
dans types.py n'a pas de champ total, mais séparé items
et required_keys
. La totalité impliquerait que items.keys()==required_keys
mais l'implémentation fait des hypothèses différentes, telles que can_be_false
Reposant uniquement sur items
. total=False
Devrait en principe signifier que required_keys
Est vide.
La source CPython pour _ TypedDictMeta révèle au moins que l'argument total
et __total__
Dunder sont une seule et même chose, bien que la source se décrit TypedDict
elle-même comme msgstr "peut être ajouté bientôt".
TypedDict
a été accepté dans Python 3.8 via PEP 589 . À partir de Python, il apparaît __total__
est un indicateur booléen défini sur True
par défaut:
tot = TypedDict.__total__
print(type(tot))
print(tot)
# <class 'bool'>
# True
Comme mentionné dans d'autres articles, les détails de cette méthode sont limités dans le docs , mais le lien de @Yann Vernier vers le code source CPython suggère fortement __total__
est lié au nouveau mot clé total
introduit dans Python 3.8 :
# cypthon/typing.py
class _TypedDictMeta(type):
def __new__(cls, name, bases, ns, total=True):
"""Create new typed dict class object.
...
"""
...
if not hasattr(tp_dict, '__total__'):
tp_dict.__total__ = total
...
Comment ça marche?
Synopsis: par défaut, toutes les clés sont requises lors de l'instanciation d'un TypedDict
défini. total=False
remplace cette restriction et autorise les clés facultatives. Voir la démonstration suivante.
Étant donné
Une arborescence de répertoires de test:
Code
Fichiers dans le répertoire de test:
# rgb_bad.py
from typing import TypedDict
class Color(TypedDict):
r: int
g: int
b: int
a: float
blue = Color(r=0, g=0, b=255) # missing "a"
# rgb_good.py
from typing import TypedDict
class Color(TypedDict, total=False):
r: int
g: int
b: int
a: float
blue = Color(r=0, g=0, b=255) # missing "a"
Démo
Si une clé est manquante, mypy se plaindra à la ligne de commande:
> mypy code/rgb_bad.py
code\rgb_bad.py:11: error: Key 'a' missing for TypedDict "Color"
...
Réglage total=False
autorise les clés optionnelles:
> mypy code/rgb_good.py
Success: no issues found in 1 source file
Voir aussi
TypedDict
dans Python 3.8 par Real Pythontyping-extensions
package pour utiliser TypedDict
in Python 3.5, 3.6