Qual è il significato dell'attributo __total__ dunder in Python 3?


17

In Python 3.8 appena rilasciato c'è una nuova annotazione di tipo typing.TypedDict. La sua documentazione lo menziona

Le informazioni sul tipo per l'introspezione sono accessibili tramite Point2D.__annotations__e Point2D.__total__. [....]

Sebbene __annotations__sia noto, essendo stato introdotto in PEP 3107 , non riesco a trovare alcuna informazione su __total__. Qualcuno potrebbe spiegarne il significato e, se possibile, collegarsi a fonti autorevoli?


4
Tipico. Il 99% degli typinginterni non è documentato e la parte che è documentata è scarsamente documentata.
Aran-Fey,

Risposte:


3

Sto indovinando che il __total__campo indica se le istanze devono essere complete (impostazione predefinita) o meno (tutti i campi facoltativi). Ho iniziato la mia ricerca su PEP 589 , che ha introdotto TypedDicte descrive la totalità in quanto tale. Ha usato un totalargomento, che avrebbe senso rinominare lo stile dunder per la class sintassi. Tuttavia, non ho trovato quando si è verificata tale ridenominazione.

Esaminando MyPy, che è il controllo del tipo effettivo che si prende cura di queste annotazioni, c'è una documentazione simile su TypedDicte totalità , ma ancora nessun riferimento alla sintassi del dunder. Scavare nella sua implementazione ha portato a una maggiore confusione, come TypedDictTypein types.py non ha un campo totale, ma separato itemse required_keys. La totalità implicherebbe ciò, items.keys()==required_keysma l'implementazione fa ipotesi diverse, come can_be_falseaffidarsi itemssolo. total=Falsein linea di principio dovrebbe required_keysessere vuoto.

La fonte CPython per _TypedDictMeta rivela almeno che l' totalargomento e il __total__dunder sono la stessa cosa, sebbene la fonte si descriva TypedDictcome "potrebbe essere aggiunta presto".


Accettarlo per ora - se non altro, forse renderà gli altri più disposti a farsi avanti e confutare la tua risposta: D
Antti Haapala

Personalmente sospetto can_be_falseche si tratti di un bug MyPy, probabilmente correlato al fatto di non aver pianificato di avere campi opzionali dall'inizio.
Yann Vernier,

1

TypedDictè stato accettato in Python 3.8 tramite PEP 589 . Da Python, sembra che __total__sia un flag booleano impostato di Truedefault:

tot = TypedDict.__total__
print(type(tot))
print(tot)

# <class 'bool'>
# True

Come menzionato in altri post, i dettagli su questo metodo sono limitati nei documenti , ma il link di @Yann Vernier al codice sorgente di CPython suggerisce fortemente che __total__è correlato alla nuova totalparola chiave introdotta in 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
        ...

Come funziona?

Sinossi : per impostazione predefinita, tutte le chiavi sono necessarie quando si crea un'istanza di un definito TypedDict. total=Falseignora questa limitazione e consente chiavi opzionali. Vedi la seguente dimostrazione.

Dato

Un albero di directory di test:

inserisci qui la descrizione dell'immagine

Codice

File nella directory di 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"

dimostrazione

Se manca una chiave, mypy si lamenterà dalla riga di comando:

> mypy code/rgb_bad.py
code\rgb_bad.py:11: error: Key 'a' missing for TypedDict "Color"
...

L'impostazione total=Falseconsente i tasti opzionali:

> mypy code/rgb_good.py
Success: no issues found in 1 source file

Guarda anche

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.