在 Python 中直接实例化 `typing.Union`

Gui*_*not 2 python typing pydantic

我想实例化一个打字Union来源于两类pydantic.BaseModel直接。但是我得到了一个TypeError: Cannot instantiate typing.Union.

我见过的所有示例都声明Union为类的属性(例如此处)。

以下是我想使用的最小示例。

from pydantic import BaseModel
from typing import Union

class A(BaseModel):
    a: int

class B(A):
    b: int

class C(A):
    c: str

MyUnion = Union[B, C, A]
mu = MyUnion(a=666, c='foo')  #  This command throws the TypeError
Run Code Online (Sandbox Code Playgroud)

有没有办法实现这一目标?

这是我得到的错误

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-40-8163e3490185> in <module>
----> 1 MyUnion()

c:\program files\python37\lib\typing.py in __call__(self, *args, **kwargs)
    668             raise TypeError(f"Type {self._name} cannot be instantiated; "
    669                             f"use {self._name.lower()}() instead")
--> 670         result = self.__origin__(*args, **kwargs)
    671         try:
    672             result.__orig_class__ = self

c:\program files\python37\lib\typing.py in __call__(self, *args, **kwds)
    327
    328     def __call__(self, *args, **kwds):
--> 329         raise TypeError(f"Cannot instantiate {self!r}")
    330
    331     def __instancecheck__(self, obj):

TypeError: Cannot instantiate typing.Union
Run Code Online (Sandbox Code Playgroud)

LtW*_*orf 6

联盟不是这样运作的。

Union 与unionC 中的the 相同。

这意味着变量可以是类型 A 或类型 B。

例如

def f(a: Union[int, str]) -> None:
   ...
Run Code Online (Sandbox Code Playgroud)

这意味着a可以是 anint或 a str,它们的子类,没有别的。

  • C 中的联合是一个特定的东西,一块内存可以在*任何给定时刻*解释为*一种类型或另一种类型*。即`union foo {int x; float y};` 然后是类似 `union foo; 的东西 foo.x = 4;`,那么我可以做类似 `printf("%d\n", foo.x); 的事情 printf("%d\n", foo.y)`,也就是说,联合的行为就像一个带有成员的结构体,只是这些成员共享内存。Python 没有这样的东西。虽然从类型论的角度来看,这可以被认为是求和类型,这就是 Union 在 Python 中的含义,但这并不意味着 Python Union 类似于 C 的 union。 (4认同)

小智 5

您正在寻找的是parse_obj_as

https://pydantic-docs.helpmanual.io/usage/models/#parsing-data-into-a-specified-type

from pydantic import BaseModel, parse_obj_as
from typing import Union

class A(BaseModel):
    a: int

class B(A):
    b: int

class C(A):
    c: str

MyUnion = Union[B, C, A]
mu = parse_obj_as(MyUnion, {"a":666, "c":'foo'}) 
mu
# >>> C(a=666, c='foo')
Run Code Online (Sandbox Code Playgroud)