On 12/31/2020 3:18 PM, Christopher Barker wrote:
On Thu, Dec 31, 2020 at 11:51 AM Eric V. Smith <eric@trueblade.com> wrote:
I'd suggest you just write your own function to do this. I consider
adding dataclasses.asdict and .astuple to be mistakes.
I agree there -- if you want something that can be used like this -- use a dict in the first place :-)
Eric: what do you think about adding a "shallow" (or "deep") flag to dataclasses.asdict()that would then upack only the top-level dataclass?
I'm not opposed to it. Since I can't make asdict/astuple go away, I might as well make them more useful.
Currently a deep copy is made:
@dataclass
class F:
l: Optional[list]
f: Optional["F"]
mylist = [1, 2, 3]
f = F(mylist, None)
f1 = F(mylist, f)
>>> f = F(mylist, None)
>>> f1 = F(mylist, f)
>>> asdict(f)
{'l': [1, 2, 3], 'f': None}
>>> asdict(f)['l'] is mylist
False
>>> asdict(f1)
{'l': [1, 2, 3], 'f': {'l': [1, 2, 3], 'f': None}}
>>> asdict(f1)['f']['l']
[1, 2, 3]
>>> asdict(f1)['f']['l'] is mylist
False
I think what we'd want is to just turn the top-level dataclass in to a dict, but then not recurse _and_ only make a shallow copy.
Something like:
>>> asdict(f1, mumble_mumble=False)
{'l': [1, 2, 3], 'f': F(l=[1, 2, 3], f=None)}
>>> asdict(f1)['l'] is mylist
True
>>> asdict(f1)['f'] is f
True
Since the 'f' member wouldn't be a copy (I hope there's agreement here), I'd think the 'l' member should also not be a copy.
The question then is: what's a good name for my "mumble_mumble"
argument? Does "deep=False" make sense? Or is it "recurse=False"?
Or maybe it should just be a separate function. The intent of
doing the shallow copy seems different than asdict() currently:
asdict() is designed to turn everything to a dict, recursively.
The target is json, but I'm not sure how well it fills that need.
As I said, I don't think asdict() is a great example of API
design, and I wish I'd left it out.
Having some convoluted combination of not recursing but making a deep copy seems wrong to me.
Eric