<html><head><meta http-equiv="Content-Type" content="text/html; charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div class="">Well that seems super unfortunate. You can opt out of the auto generate constructor and do it yourself:</div><div class=""><br class=""></div><div class="">  @dataclass(init=False)<br class="">  class Foo:<br class="">      foo: str<br class="">      bar: str = None<br class="">      baz: str<br class=""><br class="">      def __init__(self, *, foo, bar = None, baz):<br class="">          self.foo = foo<br class="">          self.bar = bar<br class="">          self.baz = baz<br class="">    <br class=""><br class="">  Foo(foo='a', bar='b', baz='c')</div><div class=""><br class=""></div><div class="">but this seems to take away from the utility of dataclasses. One could imagine there being a new argument to @dataclass that would make this work. Something like:</div><br class=""><div><br class=""></div><div>@dataclass(init_kwargs_only=True)<br class="">  class Foo:<br class="">      foo: str<br class="">      bar: str = None<br class="">      baz: str<br class=""><br class=""></div><div>where you would then get an auto generated constructor like with keyword only arguments. Personally I think this should have been the default, but it's at least a nice addition now.</div><div><br class=""></div><div>/ Anders</div><div><br class=""></div><div><br class=""><blockquote type="cite" class=""><div class="">On 24 Oct 2018, at 05:13, Philip Martin <<a href="mailto:philip.martin2007@gmail.com" class="">philip.martin2007@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div dir="ltr" class=""><div class="">Hi, I just started to use the new dataclasses module. My initial use case boils down to somewhere between a namedtuple and a class where I want a record with a few methods.</div><div class=""><br class=""></div><div class="">Mainly, I am trying to build a specific record from various sources, and then have the class handle validation and serialization. One roadblock I have found is that I can't use the field order I define for the class to say write out a csv file if any of the fields have default value. I know this bucks Python's args, kwargs ordering, but I think having the ability define optional arguments and required arguments in any order helps improve the classes intended usability. For instance, imagine "account_description_2" is None for most sources, but must appear before "other_required_field" in a CSV exported file. I think it would be useful to be able to do the following:<br class=""></div><div class=""><br class=""></div><div class="">import csv<br class="">from datetime import date<br class="">from dataclasses import dataclass, fields<br class="">from typing import List<br class=""><br class="">OBJECT_SERIALIZERS = {date: date.isoformat}<br class=""><br class="">@dataclass<br class="">class Account:<br class="">    account_id: str<br class="">    account_description: str<br class="">    account_description_2: str = None<br class=""><br class="">    # INVALID<br class="">    other_required_field: str<br class=""><br class="">    def serialize(self):<br class="">        for field in fields(self):<br class="">            value = getattr(self, <a href="http://field.name/" class="">field.name</a>)<br class="">            serializer = OBJECT_SERIALIZERS.get(field.type, None)</div><div class=""><br class="">            if serializer:<br class="">                value = serializer(value)<br class="">            yield value<br class=""><br class="">    @property<br class="">    def field_names(self):<br class="">        return [<a href="http://field.name/" class="">field.name</a> for field in fields(self)]<br class=""><br class="">    @classmethod<br class="">    def from_source_a(cls, record):<br class="">        return cls(account_id=record['account_code'],<br class="">                   account_description=record['account_name'],<br class="">                   other_required_field=record['other_field'])<br class=""><br class="">@dataclass<br class="">class AccountList:<br class="">    accounts: List[Account]<br class=""><br class="">    @property<br class="">    def field_names(self):<br class="">        return [<br class="">            <a href="http://field.name/" class="">field.name</a> for field in fields(fields(self)[0].type.__args__[0])<br class="">        ]<br class=""><br class="">    @property<br class="">    def record_field(self):<br class="">        return fields(self)[0].name<br class=""><br class="">    def to_csv(self, path):<br class="">        with open(path, 'w') as file:<br class="">            self.write_file(file)<br class=""><br class="">    def write_file(self, file):<br class="">        records_field = self.record_field<br class=""><br class="">        writer = csv.writer(file)<br class="">        writer.writerow(self.field_names)<br class="">        writer.writerows(<br class="">            record.serialize() for record in getattr(self, records_field)<br class="">        )<br class=""></div><div class=""><br class=""></div></div></div>
_______________________________________________<br class="">Python-ideas mailing list<br class=""><a href="mailto:Python-ideas@python.org" class="">Python-ideas@python.org</a><br class="">https://mail.python.org/mailman/listinfo/python-ideas<br class="">Code of Conduct: http://python.org/psf/codeofconduct/<br class=""></div></blockquote></div><br class=""></body></html>