Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python dataclass default factory with data from another field

I have a dataclass with a field of metadata, I want to extract info from it to put in other field in the dataclass, but I'm not sure if it's possible/advisable.

I tried something like that:

def get_platform_from_metadata(metadata: pd.DataFrame) -> str | None:
    platform = metadata['platform'].iloc[0]
    if platform:
        return platform_mapper.get(platform[:-1])
    return None


@dataclass(frozen=True, slots=True)
class Data:
    metadata: field(default_factory=pd.DataFrame)
    features_details: field(default_factory=pd.DataFrame)
    platform: field(default_factory=lambda: get_platform_from_metadata(metadata=metadata))

But the IDE is angry at me because he does not recognize the metadata when it's in the lambda.

I'm using python 3.10.8

like image 853
Ema Il Avatar asked Oct 22 '25 07:10

Ema Il


1 Answers

There is no possibility using the default_factory. In the docs from dataclasses it's states, that:

default_factory: If provided, it must be a zero-argument callable that will be called >when a default value is needed for this field. Among other purposes, this can be used >to specify fields with mutable default values, as discussed below. It is an error to >specify both default and default_factory. source

But a possibility would be to use __post_init__ this method will be called right after __init__ as of the docs. You could use this to solve your problem as followed:

def get_platform_from_metadata(metadata: pd.DataFrame, dflt="") -> str:
    platform = metadata['platform'].iloc[0]
    if platform:
        return platform_mapper.get(platform[:-1], dflt)
    return dflt

@dataclass(frozen=True, slots=True)
class Data:
    metadata: pd.DataFrame = field(default_factory=pd.DataFrame)
    features_details: pd.DataFrame = field(default_factory=pd.DataFrame)
    platform: str = field(init=False)

    def __post_init__(self):
        self.platform = get_platform_from_metadata(self.metadata, "")

I hope this solves your problem.

like image 63
Sifi_crafter Avatar answered Oct 23 '25 22:10

Sifi_crafter



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!