<div dir="ltr"><div>Hi, first post here.</div><div><br></div><div>My two cents:</div><div><br></div>Here's a list of "prior arts" that I have collected over the years, besides attrs, that address similar needs (and often, much more):<div><br></div><div>- <a href="https://github.com/bluedynamics/plumber">https://github.com/bluedynamics/plumber</a></div><div>- <a href="https://github.com/ionelmc/python-fields">https://github.com/ionelmc/python-fields</a></div><div>- <a href="https://github.com/frasertweedale/elk">https://github.com/frasertweedale/elk</a></div><div>- <a href="https://github.com/kuujo/yuppy">https://github.com/kuujo/yuppy</a></div><div><br></div><div>Regarding the name, 'dataclass', I agree that it can be a bit misleading (my first idea of a "dataclass" would be a class with only data and no behaviour, e.g. a 'struct', a 'record', a DTO, 'anemic' class, etc.).</div><div><br></div><div>Scala has 'case classes' with some similarities (<a href="https://docs.scala-lang.org/tour/case-classes.html">https://docs.scala-lang.org/tour/case-classes.html</a>). </div><div><br></div><div>Regards,</div><div><br></div><div>  S.</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Sep 8, 2017 at 4:57 PM, Eric V. Smith <span dir="ltr"><<a href="mailto:eric@trueblade.com" target="_blank">eric@trueblade.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I've written a PEP for what might be thought of as "mutable namedtuples with defaults, but not inheriting tuple's behavior" (a mouthful, but it sounded simpler when I first thought of it). It's heavily influenced by the attrs project. It uses PEP 526 type annotations to define fields. From the overview section:<br>
<br>
@dataclass<br>
class InventoryItem:<br>
    name: str<br>
    unit_price: float<br>
    quantity_on_hand: int = 0<br>
<br>
    def total_cost(self) -> float:<br>
        return self.unit_price * self.quantity_on_hand<br>
<br>
Will automatically add these methods:<br>
<br>
  def __init__(self, name: str, unit_price: float, quantity_on_hand: int = 0) -> None:<br>
      <a href="http://self.name" rel="noreferrer" target="_blank">self.name</a> = name<br>
      self.unit_price = unit_price<br>
      self.quantity_on_hand = quantity_on_hand<br>
  def __repr__(self):<br>
      return f'InventoryItem(name={<a href="http://self.name" rel="noreferrer" target="_blank">self.nam<wbr>e</a>!r},unit_price={self.unit_pri<wbr>ce!r},quantity_on_hand={self.<wbr>quantity_on_hand!r})'<br>
  def __eq__(self, other):<br>
      if other.__class__ is self.__class__:<br>
          return (<a href="http://self.name" rel="noreferrer" target="_blank">self.name</a>, self.unit_price, self.quantity_on_hand) == (<a href="http://other.name" rel="noreferrer" target="_blank">other.name</a>, other.unit_price, other.quantity_on_hand)<br>
      return NotImplemented<br>
  def __ne__(self, other):<br>
      if other.__class__ is self.__class__:<br>
          return (<a href="http://self.name" rel="noreferrer" target="_blank">self.name</a>, self.unit_price, self.quantity_on_hand) != (<a href="http://other.name" rel="noreferrer" target="_blank">other.name</a>, other.unit_price, other.quantity_on_hand)<br>
      return NotImplemented<br>
  def __lt__(self, other):<br>
      if other.__class__ is self.__class__:<br>
          return (<a href="http://self.name" rel="noreferrer" target="_blank">self.name</a>, self.unit_price, self.quantity_on_hand) < (<a href="http://other.name" rel="noreferrer" target="_blank">other.name</a>, other.unit_price, other.quantity_on_hand)<br>
      return NotImplemented<br>
  def __le__(self, other):<br>
      if other.__class__ is self.__class__:<br>
          return (<a href="http://self.name" rel="noreferrer" target="_blank">self.name</a>, self.unit_price, self.quantity_on_hand) <= (<a href="http://other.name" rel="noreferrer" target="_blank">other.name</a>, other.unit_price, other.quantity_on_hand)<br>
      return NotImplemented<br>
  def __gt__(self, other):<br>
      if other.__class__ is self.__class__:<br>
          return (<a href="http://self.name" rel="noreferrer" target="_blank">self.name</a>, self.unit_price, self.quantity_on_hand) > (<a href="http://other.name" rel="noreferrer" target="_blank">other.name</a>, other.unit_price, other.quantity_on_hand)<br>
      return NotImplemented<br>
  def __ge__(self, other):<br>
      if other.__class__ is self.__class__:<br>
          return (<a href="http://self.name" rel="noreferrer" target="_blank">self.name</a>, self.unit_price, self.quantity_on_hand) >= (<a href="http://other.name" rel="noreferrer" target="_blank">other.name</a>, other.unit_price, other.quantity_on_hand)<br>
      return NotImplemented<br>
<br>
Data Classes saves you from writing and maintaining these functions.<br>
<br>
The PEP is largely complete, but could use some filling out in places. Comments welcome!<br>
<br>
Eric.<br>
<br>
P.S. I wrote this PEP when I was in my happy place.<br>
<br>
______________________________<wbr>_________________<br>
Python-Dev mailing list<br>
<a href="mailto:Python-Dev@python.org" target="_blank">Python-Dev@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/python-dev" rel="noreferrer" target="_blank">https://mail.python.org/mailma<wbr>n/listinfo/python-dev</a><br>
Unsubscribe: <a href="https://mail.python.org/mailman/options/python-dev/sfermigier%2Blists%40gmail.com" rel="noreferrer" target="_blank">https://mail.python.org/mailma<wbr>n/options/python-dev/sfermigie<wbr>r%2Blists%40gmail.com</a><br>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr">Stefane Fermigier - <a href="http://fermigier.com/" target="_blank">http://fermigier.com/</a> - <a href="http://twitter.com/sfermigier" target="_blank">http://twitter.com/sfermigier</a> - <a href="http://linkedin.com/in/sfermigier" target="_blank">http://linkedin.com/in/sfermigier</a><br>Founder & CEO, Abilian - Enterprise Social Software - <a href="http://www.abilian.com/" target="_blank">http://www.abilian.com/</a><br>Chairman, Free&OSS Group / Systematic Cluster - <a href="http://www.gt-logiciel-libre.org/" target="_blank">http://www.gt-logiciel-libre.org/</a><br>Co-Chairman, National Council for Free & Open Source Software (CNLL) - <a href="http://cnll.fr/" target="_blank">http://cnll.fr/</a><div>Founder & Organiser, PyData Paris - <a href="http://pydata.fr/" target="_blank">http://pydata.fr/</a><br></div><div>---</div><div><div>“You never change things by fighting the existing reality. To change something, build a new model that makes the existing model obsolete.” <span style="font-size:12.8px">— R. Buckminster Fuller</span></div></div><div><br><br></div></div></div></div></div></div></div></div>
</div>