Python 3の__total__ dunder属性の意味は何ですか?


17

新しくリリースされたPython 3.8には、新しい型注釈がありtyping.TypedDictます。そのドキュメントには、

イントロスペクションのタイプ情報にはPoint2D.__annotations__、およびからアクセスできますPoint2D.__total__。[....]

しばらくは__annotations__で導入された、よく知られているPEP 3107、私は上の任意の情報を見つけることができません__total__。誰かがその意味を説明し、可能であれば信頼できる情報源にリンクすることはできますか?


4
典型的な。typing内部の99%は文書化されておらず、文書化されている部分の文書化も不十分です。
Aran-Fey

回答:


3

この__total__フィールドは、インスタンスが完全でなければならない(デフォルト)かそうでない(すべてのフィールドはオプション)かを示していると思います。私はPEP 589から検索を開始しましたTypedDict。この記事では、全体性を紹介し、説明しています。これはtotal引数を使用しましたが、class 構文のdunder-styleの名前を変更することには意味があります。ただし、そのような名前変更がいつ行われたかはわかりませんでした。

これらの注釈を処理する実際の型チェッカーであるMyPyを見ると、同様のドキュメントがTypedDictあり、全体性がありますが、ここでもdunder構文への参照はありません。より多くの混乱につながったその実施に掘る、とTypedDictTypetypes.pyで合計フィールドを持っていますが、分離しないitemsrequired_keys。全体性はそれを意味しますitems.keys()==required_keysが、実装は単独にcan_be_false依存するなど、さまざまな仮定を行いitemsます。total=False原則的にrequired_keysは空である必要があります。

_TypedDictMetaのCPythonソースは、少なくともtotal引数と__total__ダンダーが同じであることを明らかにしていますが、ソースはTypedDict「すぐに追加される可能性がある」と説明しています。


今のところこれを受け入れる-他に何もないとしても、おそらく他の人が前に出てあなたの答えに
異議を唱える

私は個人的にcan_be_false、それがMyPyのバグであると疑っています。
Yann Vernier

1

TypedDictPEP 589を介してPython 3.8で受け入れられました。Pythonから__total__は、Trueデフォルトでブールフラグが設定されているように見えます。

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

# <class 'bool'>
# True

他の投稿で述べたように、このメソッドの詳細はdocsで制限されていますが、CPythonソースコードへの@Yann Vernierのリンク__total__、Python 3.8で導入された新しいtotalキーワードに関連していることを強く示唆しています

# 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
        ...

どのように機能しますか?

概要:デフォルトでは、定義済みのをインスタンス化するときにすべてのキーが必要ですTypedDicttotal=Falseこの制限を無効にし、オプションのキーを許可します。次のデモをご覧ください。

与えられた

テストディレクトリツリー:

ここに画像の説明を入力してください

コード

テストディレクトリ内のファイル:

# 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"

デモ

キーがない場合、mypyはコマンドラインで文句を言うでしょう:

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

total=Falseオプションのキーを許可する設定:

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

こちらもご覧ください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.