Python 3中__total__ dunder属性的含义是什么?


17

在新发布的Python 3.8中,有一个新类型的注释typing.TypedDict。其文档中提到

可以通过Point2D.__annotations__和访问用于自省的类型信息Point2D.__total__。[....]

虽然__annotations__是众所周知的,但已在PEP 3107中引入,但我在上找不到任何信息__total__。谁能解释它的含义,并在可能的情况下链接到权威资料来源?


4
典型。99%的typing内部零件没有记录,并且零件记录得很差。
阿兰·菲

Answers:


3

我猜想该__total__字段表示实例是否必须完整(默认)或(所有字段可选)。我从PEP 589开始搜索,PEP 589对此进行了介绍TypedDict和描述。它使用了一个total参数,将class 语法重命名为dunder样式将很有意义。但是,我没有发现何时进行这样的重命名。

查看MyPy(这是关心这些批注的实际类型检查器),上面有关于TypedDictand totality的相似文档,但同样没有引用dunder语法。深入研究其实现会导致更多的混乱,因为TypedDictType在types.py中没有总字段,而是将items和分开required_keys。总体而言,这意味着items.keys()==required_keys但该实现会做出不同的假设,例如单独can_be_false依赖itemstotal=False原则上应该required_keys是空的。

_TypedDictMeta的CPython源代码至少表明该total参数和__total__dunder是相同的,尽管该源代码将TypedDict自身描述为“可能会很快添加”。


现在接受这一点-如果没有别的,也许它将使其他人更愿意挺身而出并驳斥您的答案:D
Antti Haapala 19-10-17

我个人怀疑这can_be_false是MyPy错误,可能与从一开始就没有计划具有可选字段有关。
Yann Vernier,

1

TypedDict已通过PEP 589在Python 3.8中接受。在Python中,似乎__total__是一个True默认设置为boolean标志:

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

# <class 'bool'>
# True

如其他文章所述,有关此方法的详细信息在文档中受到限制,但是@Yann Vernier指向CPython源代码的链接强烈建议__total__Python 3.8中引入的new 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
        ...

它是如何工作的?

简介:默认情况下,实例化define时需要所有键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

也可以看看

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.