Reputation: 23
I'm trying to construct a sequence of pydantic objects which all have one attribute set to a specific single instanciated value, but when doing that, the pydantic constructor always allocates a copy of the instance to each object. Is there a way to prevent that behaviour?
Example:
from abc import ABC
from pydantic import BaseModel
class Solver(BaseModel):
pass
class MyClass(Solver):
chain: tuple | None = None
class AttributeClass(Solver):
myvar: float | None = None
class System(ABC):
solver = None
one_var = 1
chain =[AttributeClass(myvar=one_var) for _ in range(1,5)]
class MySystem(System):
solver = MyClass(chain=chain)
if __name__ == "__main__":
my_instance = MySystem()
print("original ID: ", id(one_var))
for i,s in enumerate(my_instance.solver.chain):
print(f"ID n° {i+1}: {id(s.myvar)}")
Here I would like all the elements in my_instance.solver.chain to have their attributes myvar set to one_var and not to a copy of it.
I have tried to add a Config class inside my AttributeClass and tried several options including copy_on_model_validation = False, but none did the trick.
Configurations: python 3.11 and pydantic 1.10 (I have the same issue with 2.4)
Upvotes: 2
Views: 325
Reputation: 572
Please refer to the examples below.
from pydantic import BaseModel
ONE_STRING = "foo"
class AttributeClass(BaseModel):
mystring: str
class MyClass(BaseModel):
attr: tuple[AttributeClass, ...]
if __name__ == "__main__":
print(f'{id(ONE_STRING) = }')
# > id(ONE_STRING) = 4334687984
# [1] Use `ONE_STRING`
my_instance = MyClass(
attr=tuple(AttributeClass(mystring=ONE_STRING) for _ in range(1, 5))
)
for i, s in enumerate(my_instance.attr):
print(f"mystring ID n° {i}: {id(s.mystring)}")
# > mystring ID n° 0: 4334687984
# > mystring ID n° 1: 4334687984
# > mystring ID n° 2: 4334687984
# > mystring ID n° 3: 4334687984
# [2] `attr` object <- same instance
my_attr_cls = AttributeClass(mystring=ONE_STRING)
my_instance_2 = MyClass(attr=tuple(my_attr_cls for _ in range(1, 5)))
for i, s in enumerate(my_instance_2.attr):
print(f"attr ID n° {i}: {id(s)}")
# > attr ID n° 0: 4354609296
# > attr ID n° 1: 4354609296
# > attr ID n° 2: 4354609296
# > attr ID n° 3: 4354609296
Upvotes: 0