简体   繁体   English

如何在 Python3/Pydantic 中定义具有互斥成员/字段的 class

[英]How to define a class with mutually exclusive members/fields in Python3/Pydantic

I have a class called GeoLocation with fields (point and region) that are mutually exclusive.我有一个名为GeoLocation的 class,其字段(点和区域)相互排斥。 How do I define the class?如何定义 class?

Python3 code: Python3代码:

from enum import Enum
from typing import Optional
from pydantic import BaseModel

class Point(BaseModel):
    latitude: float
    longitude: float

class Ellipse(BaseModel):
    center: Point
    semiMajorAxis: Optional[float] = None

# point and region are mutually exclusive. Exactly one must be present.
class GeoLocation(BaseModel):
    point:Ellipse
    region:Polygon
    confidence: Optional[int] = None

Expected json output after serialization:序列化后预期为 json output:

{
"location": {
      "point": {
       "center": {"latitude": 37.0, "longitude": -101.3}
              }
       }
}

How do I define the GeoLocation class in python3 or pydantic such that point and region are mutually exclusive?如何在python3pydantic中定义GeoLocation class 使得pointregion互斥? I was able to implement this in Rust by defining an enum of with two struct as shown below.通过定义一个具有两个structenum ,我能够在Rust中实现这一点,如下所示。

Rust Code Rust 代码

#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "lowercase")]
pub enum Loc {
    Point(Ellipse),
    Region(Polygon),
}

#[derive(Serialize, Deserialize, Debug)]
pub struct GeoLocation {
    #[serde(flatten)]
    pub loc: Loc, // point and region are  mutually exclusive

    #[serde(skip_serializing_if = "Option::is_none")]
    pub confidence: Option<Int>, // OPTIONAL
}

Can I define an enum of classes in python3?我可以在 python3 中定义类的enum吗? Something like the following code.类似于下面的代码。 If yes, how do I initialize Loc如果是,我如何初始化Loc

class Ellipse(BaseModel):
    center: Point
    semiMajorAxis: Optional[float] = None

class Polygon(BaseModel):
    exterior: Point

# Note: point and region are mutually exclusive.  
# Exactly one must be present.
class Loc(Enum):
    point = Ellipse
    region = Polygon

class GeoLocation(BaseModel):
    loc: Loc
    confidence: Optional[int] = None

Thanks谢谢

Since you have the loc field as an enum value, this wouldn't be any different from using the Union typing class (or in Python 3.10, using the typing or operator, | ).由于您将loc字段作为枚举值,这与使用Union输入 class(或在 Python 3.10 中,使用输入或运算符| )没有任何不同。

class GeoLocation(BaseModel):
    loc: Union[Ellipse, Polygon]  # loc: Ellipse | Polygon,

This should give you the same structure as in your Rust example.这应该为您提供与 Rust 示例中相同的结构。

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

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