Pydantic model calculate property only once

Viewed 446

I have a model with a calculated value that is expensive to calculate. I need to call the results in several places that's why on the first call I want to calculate this value and then return the calculated value assuming other values do not change.

My own solution is to have an internal attribute that is set the first time the property method is called:

from pydantic import BaseModel

class MyModel(BaseModel):
    
    value1: int
    _value2: int

    @property
    def value2(self):
        if not hasattr(self, '_value2'):
            print('calculated result')
            self._value2 = self.value1*3
        return self._value2

This would work with a regular class, but with a pydantic model this fails:

>> mm = MyModel(value1=2)
>> mm.value2
calculated result
ValueError: "MyModel" object has no field "_value2"
1 Answers

Setting underscore_attrs_are_private to True solves the error. Also disbale mutations on the object covers the assumption stated above.

from pydantic import BaseModel

class MyModel(BaseModel):
    
    value1: int
    _value2: int

    class Config:
        allow_mutation = False
        underscore_attrs_are_private = True
        extra = "forbid"
        strict = True
        validate_assignment = True
        
    @property
    def value2(self):
        print('calculated result')
        self._value2 = self.value1*3
        return self._value2
Related