Assume I have the following classes:
@dataclass
class Image:
array: np.ndarray
@dataclass
class Label:
array: np.ndarray
@dataclass
class Sample:
image: Image
label: Label
with the following factory_boy factories:
class ImageFactory(factory.Factory):
class Meta:
model = Image
class Params:
shape = (64, 64)
array = factory.LazyAttribute(lambda o: np.random.random(o.shape))
class LabelFactory(factory.Factory):
class Meta:
model = Label
class Params:
shape = (64, 64)
array = factory.LazyAttribute(lambda o: np.random.randint(0, 2, o.shape))
Now, the SampleFactory is not as straightforward. I need to create an Image and Label that are related. Since this:
class SampleFactory(factory.Factory):
class Meta:
model = Sample
image = factory.SubFactory(ImageFactory)
label = factory.SubFactory(LabelFactory)
generates independent Image and Label classes. Assume I have a random_sample function that generates the arrays used by classes Image and Label. How could I use this in the SampleFactory? Furthermore, assume now the SampleFactory has a Param shape, used in the random_sample i.e. random_sample(shape) how would the implementation on the SampleFactory be?
Update 1
Seems this may be used, not sure if it's the best way:
class SampleFactory(factory.Factory):
class Meta:
model = Sample
class Params:
shape = (32, 32)
@classmethod
def _create(cls, model_class, *args, **kwargs):
params = {k: v.value for k, v in cls._meta.parameters.items()}
image_array, label_array = random_sample(**params)
image = Image(array=image_array)
label = Label(array=label_array)
return Sample(image=image, label=label)
Update 2
Using exclude in the Meta is a better option since it won't affect subclassing:
class SampleFactory(factory.Factory):
class Meta:
model = Sample
exclude = ("data",)
class Params:
shape = (32, 32)
data = factory.LazyAttribute(lambda o: random_sample(o.shape))
image = factory.LazyAttribute(lambda o: Image(o.data[0]))
label = factory.LazyAttribute(lambda o: Label(o.data[1]))