【问题标题】:Unpacking class definition to share variable names between objects解包类定义以在对象之间共享变量名
【发布时间】:2019-12-01 17:14:55
【问题描述】:

虽然可能有更好的方式来表达这个问题,但这个想法非常简单。

我有两节课。包裹和包裹请求。 ParcelRequest 在 API 中用于请求具有给定参数的 Parcel 的信息和

实际上,ParcelRequest 需要与 Parcel 相同的所有参数,但需要一个额外的 quantity 值。

from pydantic import BaseModel

class Parcel(BaseModel):
    length: float
    width: float
    height: float
    weight: float


class ParcelRequest(BaseModel):
    length: float
    width: float
    height: float
    weight: float
    quantity: int

有没有办法让 Parcel 和 ParcelRequest 在 Parcel 被修改时保持“同步”?

from pydantic import BaseModel

class Parcel(BaseModel):
    length: float
    width: float
    height: float
    weight: float


class ParcelRequest(BaseModel):
    # unpack Parcel attributes here
    quantity: int

注意:在此特定示例中,我们无法更改传入请求的结构。这意味着,我们不能简单地在 ParcelRequest 中包含一个引用 Parcel 对象的“parcel”属性,因为它会改变请求的结构。

问题是这是否可以做到。但作为奖励,应该这样做吗?我的信念是,虽然 API 会随着 Parcel 的发展而与它保持同步,但开发人员可能会通过更新 Parcel 无意中破坏 API,除非经过仔细处理并且没有经过适当的测试。

【问题讨论】:

  • 为什么不在 ParcelRequest 中放一个指向 Parcel 的“指针”?
  • @thebjorn 好问题,我忘了包括这个。对传入请求正文的结构有一定的要求。使用指针而不是列出的属性会破坏该要求。
  • 非声明性方法可能是更好的选择。 common = {'length': float, ...},然后是 Parcel = type('Parcel', (BaseModel,), common)ParcelRequest = type('ParselRequest', (BaseModel,), dict(common, quantity=int))。如果BaseModel 是某个元类的包装器,您可以直接调用它而不是调用type

标签: python python-3.x pydantic


【解决方案1】:

不要重复自己,说出要继承自的类:

class MetaParcel(BaseModel):
    length: float
    width: float
    height: float
    weight: float


class ParcelRequest(MetaParcel):
    quantity: int

【讨论】:

  • 所以这是显而易见的答案,但这是最佳实践吗?由于每个模型的意图不同,扩展它们是否有意义?还是我们不会对数据类应用相同的原则?
  • 说,对我们的 Parcel 类添加一些逻辑是有意义的。 ParcelRequest 现在扩展了这个逻辑。但是,ParcelRequest 不打算用于数据模型以外的任何东西。不应要求 ParcelRequest 扩展它无意使用或有逻辑用途的功能。
  • @JustianMeyer:你可能想看看data classes
  • @Jan 我怀疑pydantic.BaseModel 已经在实现类似数据类的东西。 (事实上​​,文档讨论了使用数据类而不是BaseModel:pydantic-docs.helpmanual.io/usage/dataclasses)。
  • 这种继承方式是正确的。如果您真的想要包裹上的属性而不是包裹请求,请使用公共基类。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-28
  • 2012-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多