On 12/31/2020 3:59 PM, Eric V. Smith wrote:
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 <mailto: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