Python 3 中的 __total__ dunder 属性是什么意思?
What is the meaning of __total__ dunder attribute in Python 3?
在新发布的Python 3.8中有一个新的类型注解typing.TypedDict
。它的文档提到
The type info for introspection can be accessed via Point2D.__annotations__
and Point2D.__total__
. [....]
虽然 __annotations__
是众所周知的,已在 PEP 3107 中介绍过,但我找不到关于 __total__
的任何信息。谁能解释一下它的含义,如果可能的话,可以链接到权威来源吗?
我猜测 __total__
字段表示实例是否必须完整(默认)或不完整(所有字段都是可选的)。我从 PEP 589 开始搜索,它介绍了 TypedDict
并描述了整体性。它使用了一个 total
参数,为 class
语法重命名 dunder-style 是有意义的。但是,我没有找到这样的重命名是什么时候发生的。
查看 MyPy,它是关心这些注释的实际类型检查器,similar documentation on TypedDict
and totality, but again no reference to the dunder syntax. Digging into its implementation led to more confusion, as TypedDictType
in types.py 没有总字段,而是分开的 items
和 required_keys
。整体性意味着 items.keys()==required_keys
但实现会做出不同的假设,例如 can_be_false
单独依赖 items
。 total=False
原则上应该意味着 required_keys
是空的。
_TypedDictMeta 的 CPython 源代码至少揭示了 total
参数和 __total__
dunder 是一回事,尽管源代码将 TypedDict
本身描述为 "may be added soon"。
TypedDict
通过 PEP 589 在 Python 3.8 中被接受。从 Python 看来,__total__
是一个默认设置为 True
的布尔标志:
tot = TypedDict.__total__
print(type(tot))
print(tot)
# <class 'bool'>
# True
如其他帖子所述,有关此方法的详细信息仅限于 docs, but @Yann Vernier's link to the CPython source code strongly suggests __total__
is related to the new total
keyword introduced 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
...
它是如何工作的?
概要: 默认情况下,实例化定义的 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
另请参阅
- Tweet 由 R. Hettinger 展示整体性
- PEP section PEP 589 中的全部内容
- 关于类型的文章 Section 和 Python 3.8 中的
TypedDict
由 Real Python
typing-extensions
package 在 Python 3.5、3.6 中使用 TypedDict
在新发布的Python 3.8中有一个新的类型注解typing.TypedDict
。它的文档提到
The type info for introspection can be accessed via
Point2D.__annotations__
andPoint2D.__total__
. [....]
虽然 __annotations__
是众所周知的,已在 PEP 3107 中介绍过,但我找不到关于 __total__
的任何信息。谁能解释一下它的含义,如果可能的话,可以链接到权威来源吗?
我猜测 __total__
字段表示实例是否必须完整(默认)或不完整(所有字段都是可选的)。我从 PEP 589 开始搜索,它介绍了 TypedDict
并描述了整体性。它使用了一个 total
参数,为 class
语法重命名 dunder-style 是有意义的。但是,我没有找到这样的重命名是什么时候发生的。
查看 MyPy,它是关心这些注释的实际类型检查器,similar documentation on TypedDict
and totality, but again no reference to the dunder syntax. Digging into its implementation led to more confusion, as TypedDictType
in types.py 没有总字段,而是分开的 items
和 required_keys
。整体性意味着 items.keys()==required_keys
但实现会做出不同的假设,例如 can_be_false
单独依赖 items
。 total=False
原则上应该意味着 required_keys
是空的。
_TypedDictMeta 的 CPython 源代码至少揭示了 total
参数和 __total__
dunder 是一回事,尽管源代码将 TypedDict
本身描述为 "may be added soon"。
TypedDict
通过 PEP 589 在 Python 3.8 中被接受。从 Python 看来,__total__
是一个默认设置为 True
的布尔标志:
tot = TypedDict.__total__
print(type(tot))
print(tot)
# <class 'bool'>
# True
如其他帖子所述,有关此方法的详细信息仅限于 docs, but @Yann Vernier's link to the CPython source code strongly suggests __total__
is related to the new total
keyword introduced 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
...
它是如何工作的?
概要: 默认情况下,实例化定义的 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
另请参阅
- Tweet 由 R. Hettinger 展示整体性
- PEP section PEP 589 中的全部内容
- 关于类型的文章 Section 和 Python 3.8 中的
TypedDict
由 Real Python typing-extensions
package 在 Python 3.5、3.6 中使用
TypedDict