Python TypedDict 中的任意键

huangapple go评论84阅读模式
英文:

Python arbritary keys in TypedDict

问题

你能否创建一个具有一组已知键和任意键类型的 TypedDict 吗?例如,在 TypeScript 中,我可以这样做:

from typing import TypedDict, Mapping, List, Union

class Sample(TypedDict):
    x: bool
    y: int

    labels: Mapping[str, str]
    aliases: Mapping[str, List[str]]

    # For arbitrary keys with type SomeCustomClass
    __annotations__: Mapping[str, Union[str, List[str], SomeCustomClass]]

编辑:我的问题是,我创建了一个库,其中一个函数的参数期望类型为 Mapping[str, SomeCustomClass]。我想更改类型,使其包含特殊键,类型如下:

  • labels: Mapping[str, str]
  • aliases: Mapping[str, List[str]]

但我仍希望它仍然是一个任意映射,如果键不在上述两种特殊情况中,则其类型应为 SomeCustomClass。有什么好的方法可以做到这一点吗?如果有替代方案而不会造成向后不兼容的更改,我对此不感兴趣。

英文:

Is it possible to make a TypedDict with a set of known keys and then a type for an arbitrary key? For example, in TypeScript, I could do this:

interface Sample {
  x: boolean;
  y: number;

  [name: string]: string;
}

What is the equivalent in Python?


Edit: My problem is that I make a library where a function's argument expects a type of Mapping[str, SomeCustomClass]. I want to change the type so that there are now special keys, where the types are like this:

  • labels: Mapping[str, str]
  • aliases: Mapping[str, List[str]]

But I want it to still be an arbitrary mapping where if a key is not in the two special cases above, it should be of type SomeCustomClass. What is a good way to do this? I am not interested in making a backwards-incompatible change if there is an alternative.

答案1

得分: 1

这是可能的,使用 Union 类型操作符,但不幸的是,通过这种解决方案,您失去了对必需字段的检查:

from typing import TypedDict, Union, Dict

class SampleRequiredType(TypedDict, total=True):
  x: bool
  y: int

SampleType = Union[SampleRequiredType, Dict]

# 现在所有这些字典都是有效的:

dict1: SampleType = {
  'x': True,
  'y': 123
}

dict2: SampleType = {
  'x': True,
  'y': 123,
  'z': 'my string'
}

dict3: SampleType = {
  'z': 'my string'
}
英文:

That is possible with Union type operator, but unfortunately with this solution, you lose checking the required fields:

from typing import TypedDict, Union, Dict

class SampleRequiredType(TypedDict, total=True):
  x: bool
  y: int

SampleType = Union[SampleRequiredType, Dict]

# Now all these dictionaries will be valid:

dict1: SampleType = {
  'x': True,
  'y': 123
}

dict2: SampleType = {
  'x': True,
  'y': 123
  'z': 'my string' 
}

dict3: SampleType = {
  'z': 'my string' 
}

huangapple
  • 本文由 发表于 2023年2月19日 22:48:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/75500948.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定