Example task:
``` from dataclasses import dataclass, asdict, fields from typing import List
@dataclass class Point: x: int y: int
@dataclass class Axes: title: str points: List[Point]
def plot(title: str, points: List[Point]): print(title) for point in points: print(f'x={point.x}', f'y={point.y}')
axes = Axes('example', [Point(i, i) for i in range(3)]) # Now I need to plot my axes. ```
Way 0: `plot(axes.title, axes.points)` Yes, it works great, but the topic about `dataclass2dict` conversion.
Way 1: `plot(**asdict(axes))` Using `asdict` is what comes to mind first. But it is recursive, so it won't work. `asdict`, `astuple`... is an "bad naming" example, I think. Unexpected name for a recursive function. People don't read the documentation, and even when they do, they forget. As an example: https://stackoverflow.com/q/52229521/6146442 Viewed 7k times.
Way 2: `plot(**vars(axes))` Everything seems to be good. But pseudo-fields which are `ClassVar` or `InitVar` will be returned. `asdict` use: `return tuple(f for f in fields.values() if f._field_type is _FIELD)`
Way 3: Using undocumented `__dataclass_fields__` is look like a hack.
Way 4: `plot(**{f.name: getattr(axes, f.name) for f in fields(axes)})` This will actually work. But I'm not sure about the elegance.
My suggestions:
1. Add default `True` `recursive` flag to `asdict` and implement Way 4 internally. At the same time, IDE will remind people from stackoverflow that `asdict` is recursive.
2. Or add new not-recursive function to `dataclasses` module. Leave `asdict` frozen.
3. Do nothing. Way 4 is handsome enough. Describe the way in the documentation so that people don't get confused and don't use `vars` or `asdict`.
I am ready to offer my assistance in implementation. Thank you for your attention and happy holidays!