dataclasses are the best recent addition to Python, IMO, maybe tied with ordered dicts.
Python definitely doesn't have conceptual simplicity, because there are many competing concepts in the language, and lack of focus on uniformity. (Example - enums are implemented with a metaclass and dataclasses with a class decorator - arguably the latter is the wrong choice, because it is already evident it limits what kind of features can be added to dataclasses).
Another example just because it makes me irate - `typing.NamedTuple` has been added as an "alternative" to `collections.namedtuple`. Same name, new capitalization, slightly different features. Add to that, a collection type that's inside the module `typing` which is supposed to be for.. type annotations, not actual implementations.
> (Example - enums are implemented with a metaclass and dataclasses with a class decorator - arguably the latter is the wrong choice, because it is already evident it limits what kind of features can be added to dataclasses).
I'm curious about what features can't be added to dataclasses because it's not using a metaclass.
If anything, I think that not using a metaclasses is a good thing: it allows you to use @dataclass with classes that do require a metaclass. That metaclass would likely be incompatible with the metaclass that such a hypothetical @dataclass implementation would use.
Thanks for not using metaclasses for dataclasses. I’m looking forward to all libraries replacing metaclasses. For instance, in Django, I think all their metaclasses can be replaced by __init__subclass__. The main issue I have with them is how difficult it can be to compose a new abstract class using upstream classes with them.
The reason it's not an option by default is because it would be the one case where the decorator would have to return a new class, and I didn't want to do that on the first version. As it is, @dataclass just modifies an existing class. I might bite the bullet add a slots option, and we've had discussions on adding a language feature to automatically add slots to a class, based on annotations and maybe some other magic. If we did that, we wouldn't need to return a new class. But it's not a front-burner task for me.
I really appreciate it! Only issue I see is that it won't support inherited dataclasses where the base class already defines __slots__, but I should be able to hack together support.
Maybe that would have worked better with a metaclass.
But still, I think not using a metaclass is the more flexible design. Maybe I'll add the "add_slots" behavior into the @dataclass decorator in 3.10, even though it would need to return a new class. At least it could be well documented, and I doubt it's a concern for most people.
> Thanks for working on dataclasses :) - as I said, it's my #1 new feature in Python.
I'm offended! I also wrote f-strings, but maybe that's not considered new anymore. In any event, you're welcome!
Maybe the __slots__ discussion is not really that important - it's just convenience, and the regular old method of adding slots still works. So it's a minor thing.
I have diligently converted to f-strings but it doesn't give me new expressibility like I feel dataclasses do, just convenience :)
FYI if you haven't heard of it, attrs (https://www.attrs.org/en/stable/) is a package very similar to dataclasses that does support aromatically adding __slots__. I believe dataclasses was bases on it.
Yes, attrs is the spiritual parent of dataclasses, including the decision to not use metaclasses. Thanks for mentioning this: I try to always give credit to Hynek and attrs.
No, (optional) static typing is the best recent addition to Python. It allows IDEs to catch a large variety of errors. The static type system is part of the language and has multiple implementations. It's Hindley-Milner, making it two-way, like Haskell's type system.
Python definitely doesn't have conceptual simplicity, because there are many competing concepts in the language, and lack of focus on uniformity. (Example - enums are implemented with a metaclass and dataclasses with a class decorator - arguably the latter is the wrong choice, because it is already evident it limits what kind of features can be added to dataclasses).
Another example just because it makes me irate - `typing.NamedTuple` has been added as an "alternative" to `collections.namedtuple`. Same name, new capitalization, slightly different features. Add to that, a collection type that's inside the module `typing` which is supposed to be for.. type annotations, not actual implementations.