Как создать новый экземпляр класса с новыми рандомными данными?
Условно есть такой код:
import random
class Test:
number: str = random.randint(100, 500)
test1 = Test()
test2 = Test()
assert test1.number == test2.number
Создаются 2 разных объекта, но значение number у них будет всегда одинаковое.
Как создать несколько экземпляров класса, в которых будут каждый раз генерироваться рандомные значения number (и чтобы вручную не передавать туда number=...)? Чтобы выполнялось такое условие:
test1 = Test()
test2 = Test()
assert test1.number != test2.number
Ответы (5 шт):
А вы не пробовали записывать класс в каноническом виде, с функцией инициализации экземпляров? в противном случае рандомизация у вас происходит один раз для родительского объекта.
import random
class Test:
def __init__(self):
self.number = random.randint(100, 500)
test1 = Test()
test2 = Test()
test1.number==test2.number #False
В обычном случае, вам подойдёт вариант, предложенный @strawdog:
class Test:
number: str
def __init__():
self.number = random.randint(100, 500)
Если же вы используете pydantic.BaseModel, то данные можно передать в super().__init__(**data) при инициализации:
class Test(pydantic.BaseModel):
number: str
def __init__(self, number=None, **data):
super().__init__(
number=random.randint(100, 500) if number is None else number,
**data
)
Определение поля в классе в pydantic - это значение по умолчанию для всех экземпляров, для которых такое значение не задано. По-этому, то, что вы наблюдаете - это нормальное ожидаемое поведение.
Если вам нужно создать экземпляры со случайными значениями, то делайте это в конструкторе:
class Test(pydantic.BaseModel):
number: str
def __init__(self, **data):
if 'number' not in data:
data['number'] = random.randint(100, 500)
super().__init__(**data)
Ну и еще есть factoryboy как раз для генерации тестовых данных.
Как вариант, можно передавать случайное число при инициализации объекта:
import random
from pydantic import BaseModel
class Test(BaseModel):
number: int
print(Test(number=random.randint(100, 500)).number)
print(Test(number=random.randint(100, 500)).number)
print(Test(number=random.randint(100, 500)).number)
Пример вывода:
431
448
412
Всем спасибо за ответы, они действительно правильные. Но мне кажется более изящным и читабельным следующее решение:
import random
from pydantic import BaseModel
from pydactory import Factory
class Test(BaseModel):
number: int
class TestFactory(Factory[Test]):
number: int = lambda: random.randint(100, 500)
test1: Test = TestFactory.build()
test2: Test = TestFactory.build()
assert test1.number != test2.number # True
Напишите, пожалуйста, в комментариях, что вы думаете по поводу данного решения.