简体   繁体   English

如何使用 integer 键制作 TypedDict?

[英]How to make a TypedDict with integer keys?

Is it possible to use an integer key with TypedDict (similar to dict?).是否可以使用带有 TypedDict 的 integer 键(类似于 dict?)。

Trying a simple example:尝试一个简单的例子:

    from typing import TypedDict 
    
    class Moves(TypedDict):
      0: int=1
      1: int=2

Throws: SyntaxError: illegal target for annotation抛出: SyntaxError: illegal target for annotation

It seems as though only Mapping[str, int] is supported but I wanted to confirm.似乎只支持Mapping[str, int]但我想确认一下。 It wasn't specifically stated in the Pep docs. Pep 文档中没有具体说明。

The intent of TypedDict is explicit in the PEP's abstract (emphasis added): TypedDict的意图在PEP 的摘要中是明确的(添加了重点):

This PEP proposes a type constructor typing.TypedDict to support the use case where a dictionary object has a specific set of string keys , each with a value of a specific type.这个 PEP 提出了一个类型构造函数typing.TypedDict来支持字典 object 具有一组特定的字符串键的用例,每个键都有一个特定类型的值。

and given the intended use cases are all annotable in class syntax, implicitly applies only to dict s keyed by strings that constitute valid identifiers (things you could use as attribute or keyword argument names), not even strings in general.并且鉴于预期的用例在 class 语法中都是可注释的,隐式仅适用于由构成有效标识符的字符串(您可以用作属性或关键字参数名称的东西)键入的dict s,甚至不是一般的字符串。 So as intended, int keys aren't a thing, this is just for enabling a class that uses dict -like syntax to access the "attributes" rather than attribute access syntax.因此,正如预期的那样, int键不是一个东西,这只是为了启用 class 使用类似dict的语法来访问“属性”而不是属性访问语法。

While the alternative, backwards compatible syntax , allowed for compatibility with pre-3.6 Python, allows this (as well as allowing strings that aren't valid Python identifiers), eg:虽然替代的向后兼容语法允许与 3.6 之前的 Python 兼容,但允许这样做(以及允许不是有效的 Python 标识符的字符串),例如:

Moves = TypedDict('Moves', {0: int, 1: int})

you could only construct it with dict literals (eg Moves({0: 123, 1: 456}) ) because the cleaner keyword syntax like Moves(0=123, 1=456) doesn't work.您只能使用dict文字(例如Moves({0: 123, 1: 456}) )构造它,因为像Moves(0=123, 1=456)这样的更简洁的关键字语法不起作用。 And even though that technically works at runtime (it's all just dict s under the hood after all), the actual type-checkers that validate your type correctness may not support it (because the intent and documented use exclusively handles strings that constitute valid identifiers).即使这在技术上在运行时有效(毕竟这只是dict的底层),验证您的类型正确性的实际类型检查器可能不支持它(因为意图和记录的使用专门处理构成有效标识符的字符串) .

Point is, don't do this.重点是,不要这样做。 For the simple case you're describing here (consecutive integer integer "keys" starting from zero, where each position has independent meaning, where they may or may not differ by type), you really just want a tuple anyway:对于您在此处描述的简单情况(连续的tuple integer “键”从零开始,其中每个 position 具有独立的含义,它们可能或可能不会因类型而异:)

Moves = typing.Tuple[int, int]  # Could be [int, str] if index 1 should be a string

would be used for annotations the same way, and your actual point of use in the code would just be normal tuple syntax ( return 1, 2 ).将以相同的方式用于注释,并且您在代码中的实际使用点只是普通的tuple语法( return 1, 2 )。

If you really want to be able to use the name Moves when creating instances, on 3.9+ you could use PEP 585 to do (no import required):如果您真的希望在创建实例时能够使用名称Moves ,那么在 3.9+ 上,您可以使用PEP 585来执行(无需导入):

Moves = tuple[int, int]

allowing you to write:允许你写:

return Moves((1, 2))

when you want to make an "instance" of it.当你想制作它的“实例”时。 No runtime checking is involved (it's roughly equivalent to running tuple((1, 2)) at runtime), but static type-checkers should understand the intent.不涉及运行时检查(它大致相当于在运行时运行tuple((1, 2)) ),但 static 类型检查器应该理解其意图。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM