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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With