Яке значення атрибута __total__ dunder в Python 3?


17

В нещодавно випущеному Python 3.8 є анотація нового типу typing.TypedDict. У його документації це згадується

Інформація про тип для самоаналізу може бути доступна через Point2D.__annotations__та Point2D.__total__. [....]

Хоча __annotations__це добре відомо, внісши в PEP 3107 , я не можу знайти жодної інформації __total__. Чи міг би хтось пояснити його значення та по можливості посилатися на авторитетні джерела?


4
Типовий. 99% typingвнутрішніх справ не задокументовані, а частина, яка є задокументована, погано.
Аран-Фей

Відповіді:


3

Я здогадуюсь, що __total__поле означає, чи повинні екземпляри бути повними (за замовчуванням) чи ні (усі поля необов’язково). Я розпочав свій пошук на PEP 589 , який представив TypedDictта описує сукупність як таку. Тут було використано totalаргумент, який було б доцільно перейменовувати в class синтаксисі типу " dnder" . Однак я не знайшов, коли відбулося таке перейменування.

Дивлячись на MyPy, який є фактичним перевіряючим типом, який піклується про ці анотації, є аналогічна документація про TypedDictта сукупність , але знову ж таки ніяких посилань на синтаксис dunder. Робота над його реалізацією призвела до більшої плутанини, так як TypedDictTypeу type.py не має загального поля, а окремо itemsі required_keys. Сукупність означатиме, що, items.keys()==required_keysале реалізація робить різні припущення, наприклад, can_be_falseпокладатися на itemsпоодинці. total=Falseв принципі повинно означати, що required_keysце порожньо.

Джерело CPython для _TypedDictMeta принаймні виявляє, що totalаргумент і __total__датчик - одне і те ж, хоча джерело описує TypedDictсебе як "може бути додано незабаром".


Прийнявши це зараз - якщо не що інше, можливо, це змусить інших охочіше виступити і спростувати вашу відповідь: D
Antti Haapala

Я особисто підозрюю, can_be_falseщо це помилка MyPy, можливо, пов’язана з тим, що не планували мати необов'язкові поля з самого початку.
Янна Верньє

1

TypedDictбуло прийнято в Python 3.8 через PEP 589 . З Python з'являється __total__булевий прапор, встановлений Trueза замовчуванням:

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

# <class 'bool'>
# True

Як вже згадувалося в інших публікаціях, деталі щодо цього методу обмежені у документах , але посилання @Yann Vernier на вихідний код CPython настійно підказує, що __total__це стосується нового totalключового слова, введеного в 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
        ...

Як це працює?

Короткий огляд : за замовчуванням всі кнопки потрібні при створенні інстанції визначеного TypedDict. total=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

Дивись також

  • Твіт від Р. Хеттінгера, що демонструє сукупність
  • Розділ PEP про сукупність у PEP 589
  • Стаття Розділ про типи та TypedDictна Python 3.8 від Real Python
  • typing-extensionsпакет для використання TypedDictв Python 3.5, 3.6
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.