8 ms·
As noted in the PEP data classes is a less fully-featured stdlib implementation of what attrs already provides. Unless you’re constrained to the stdlib (as thos
by reaperhulk 9y ago
As noted in the PEP data classes is a less fully-featured stdlib implementation of what attrs already provides. Unless you’re constrained to the stdlib (as those who write CPython itself of course are) you should consider taking a look at attrs first.
http://www.attrs.org/en/stable/ http://www.attrs.org/en/stable/
- oblio 9y agoThis library? http://www.attrs.org/en/stable/ http://www.attrs.org/en/stable/
- reaperhulk 9y agoYep, I’ll add the URL in my comment, sorry about that.
- shoyer 9y agoLess fully-featured, sure, but also a bit more cleanly designed (in my opinion). Are there features from attrs that you would miss with dataclasses?
- metalliqaz 9y agoThis is spot on. The design of attrs remines me a little bit of the syntax from a declarative ORM, for example. I'm sure it can do very powerful things that I've not had occasion to use, but it is heavy. The @dataclass format is very clean and seems more like the syntactic sugar that I expect from Python. One of the prime uses of a dataclass is to be a mutable namedtuple. And the syntax can be almost identical: Part = make_dataclass('Part', ['part_num', 'description', 'quantity']) (from Raymond Hettinger's twitter) This has the added benefit of not requiring type hinting, if you don't want to bother with such things.
- froztbyte 9y agoin a freshly created venv, with attrs and ipython (and deps, of course): (attrs) % ipython Python 2.7.14 (default, Oct 19 2017, 23:28:49) Type "copyright", "credits" or "license" for more information. IPython 5.6.0 -- An enhanced Interactive Python. ? -> Introduction and overview of IPython's features. %quickref -> Quick reference. help -> Python's own help system. object? -> Details about 'object', use 'object??' for extra details. In [1]: import attr In [2]: Part = attr.make_class("Part", ["part_num", "description", "quantity"]) In [3]: Part? Init signature: Part(self, part_num, description, quantity) Docstring: <no docstring> Type: type Outside of the name of the thing that creates the item, the syntax is identical to what you have here. edit: removed triple backticks, indented with 2sp according to https://news.ycombinator.com/formatdoc https://news.ycombinator.com/formatdoc rules
- deleted 9y ago[deleted]
- zackelan 9y agoattrs also has a feature that dataclasses don't currently [0]: an easy way to use __slots__ [1]. It cuts down on the per-instance memory overhead, for cases where you're creating a ton of these objects. It can be useful even when not memory-constrained, because it will throw AttributeError, rather than succeeding silently, if you make a typo when assigning to an object attribute. 0: https://www.python.org/dev/peps/pep-0557/#support-for-automatically-setting-slots https://www.python.org/dev/peps/pep-0557/#support-for-automa... 1: http://www.attrs.org/en/stable/examples.html#slots http://www.attrs.org/en/stable/examples.html#slots
- kstrauser 9y agoDoes that still matter now that PEP 412 (https://www.python.org/dev/peps/pep-0412/ https://www.python.org/dev/peps/pep-0412/) is implemented in Python 3.3 and newer?
- xapata 9y agoNo, I wouldn't bother with __slots__ in 3.7, especially with the newly optimized dict.
- markrwilliams 9y agoPEP 412 makes __dict__s more memory efficient than they were before, but not more efficient than no __dict__, which is the point of __slots__. The following program demonstrates the difference. Note that it lowers the available address space to 1GB so that memory exhaustion occurs sooner, and thus only works on UNIX-like systems that provide the resource module. import resource import sys class WithoutSlots: def __init__(self, a, b): self.a = a self.b = b class WithSlots: __slots__ = ('a', 'b') def __init__(self, a, b): self.a = a self.b = b resource.setrlimit(resource.RLIMIT_AS, (1024 ** 3, 1024 ** 3)) cls = WithSlots if sys.argv[1:] == ['slots'] else WithoutSlots count, instances = 0, [] while True: try: instances.append(cls(1, 2)) except MemoryError: break count = len(instances) del instances print(cls, count) Here are numbers from my laptop: $ python3.6 /tmp/slots.py <class '__main__.WithoutSlots'> 5830382 $ python3.6 /tmp/slots.py slots <class '__main__.WithSlots'> 16081964 That's almost 3x more instances with __slots__! This isn't the case with PyPy, though, thanks to a more efficient representation of objects: https://morepypy.blogspot.com/2010/11/efficiently-implementing-python-objects.html https://morepypy.blogspot.com/2010/11/efficiently-implementi...
- adamc 9y agoDoes attrs support type hints? I didn't see it in a quick skim... One thing the stdlib implementation has going for it: better naming. attr.ib() is not exactly crystal-clear.