最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

python - Complex Recursive Pydantic class initialization: how to have native Pydantic type checking with custom constructors - S

programmeradmin2浏览0评论

I want to use the Pydantic to model a "cartesian table" represented as a nested dictionary. Here is an example of what I can expect as input to the NestedCounts model:

{
    "x1": {
        "y1": {
            "z1": 5,
            "z2": 5
        },
        "y2": {
            "z1": 7,
            "z2": 3
        },
        "y3": {
            "z1": 8,
            "z2": 2
        }
    },
    "x2": {
        "y1": {
            "z1": 1,
            "z2": 9
        },
        "y2": {
            "z1": 2,
            "z2": 8
        },
        "y3": {
            "z1": 4,
            "z2": 6
        }
    }
}

The keys at each level will always be strings. The values at the final level will be int, and the values at a non-final level will be a recursive case.

What is the best way to model this using Pydantic? I want to model it in such a way that the native type checking is supported when instantiating a model.

Here is what I am using for now:

from __future__ import annotations
from pydantic import BaseModel

class NestedCounts(BaseModel):
    counts: dict[str, int|NestedCounts]

    @classmethod
    def from_dict(cls, data: dict) -> NestedCounts:
        if all(isinstance(v, int) for v in data.values()):
            return cls(counts=data)
        elif all(isinstance(v, dict) for v in data.values()):
            return cls(counts={k: NestedCounts.from_dict(v) for k, v in data.items()})
        else:
            raise ValueError(f"Invalid dependent variable probabilities. All values must be ints or all values must be dictionaries:\n{data}")

Is there a better way to model such input schema? I want to make sure that whatever I implement allows Pydantic's native type checking.

I want to use the Pydantic to model a "cartesian table" represented as a nested dictionary. Here is an example of what I can expect as input to the NestedCounts model:

{
    "x1": {
        "y1": {
            "z1": 5,
            "z2": 5
        },
        "y2": {
            "z1": 7,
            "z2": 3
        },
        "y3": {
            "z1": 8,
            "z2": 2
        }
    },
    "x2": {
        "y1": {
            "z1": 1,
            "z2": 9
        },
        "y2": {
            "z1": 2,
            "z2": 8
        },
        "y3": {
            "z1": 4,
            "z2": 6
        }
    }
}

The keys at each level will always be strings. The values at the final level will be int, and the values at a non-final level will be a recursive case.

What is the best way to model this using Pydantic? I want to model it in such a way that the native type checking is supported when instantiating a model.

Here is what I am using for now:

from __future__ import annotations
from pydantic import BaseModel

class NestedCounts(BaseModel):
    counts: dict[str, int|NestedCounts]

    @classmethod
    def from_dict(cls, data: dict) -> NestedCounts:
        if all(isinstance(v, int) for v in data.values()):
            return cls(counts=data)
        elif all(isinstance(v, dict) for v in data.values()):
            return cls(counts={k: NestedCounts.from_dict(v) for k, v in data.items()})
        else:
            raise ValueError(f"Invalid dependent variable probabilities. All values must be ints or all values must be dictionaries:\n{data}")

Is there a better way to model such input schema? I want to make sure that whatever I implement allows Pydantic's native type checking.

Share Improve this question edited Mar 14 at 3:51 InSync 11.1k4 gold badges18 silver badges56 bronze badges asked Mar 14 at 2:56 parth.nparth.n 1
Add a comment  | 

1 Answer 1

Reset to default 0

That's what RootModel is for:

class NestedCounts(RootModel):
    root: dict[str, "NestedCounts | int"]

input_dict = {
    "x1": {"y1": {"z1": 5, "z2": 5}, "y2": {"z1": 7, "z2": 3}, "y3": {"z1": 8, "z2": 2}},
    "x2": {"y1": {"z1": 1, "z2": 9}, "y2": {"z1": 2, "z2": 8}, "y3": {"z1": 4, "z2": 6}},
}
nested_counts = NestedCounts.model_validate(input_dict)

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论