Home > Enterprise >  Why can’t fields with default values come first?
Why can’t fields with default values come first?

Time:08-30

I got the following error using dataclasses. Does anyone knoes why this isn’t valid?

from dataclasses import dataclass


@dataclass(frozen= False)
class Contact:
    contact_id: int= 0
    contact_firstname: str
    contact_lastname: str
    contact_email: str= None

Error: Fields without default values cannot appear after fields without default values

CodePudding user response:

Fields in a dataclass are translated, in the same order, to arguments in the constructor function. So, if it were allowed, then this

@dataclass(frozen= False)
class Contact:
    contact_id: int= 0
    contact_firstname: str
    contact_lastname: str
    contact_email: str= None

would get translated to (omitting the __eq__ and all the other dataclass convenience functions)

class Contact:

    def __init__(contact_id=0, contact_firstname, contact_lastname, contact_email=None):
        self.contact_id = contact_id
        self.contact_firstname = contact_firstname
        self.contact_lastname = contact_lastname
        self.contact_email = contact_email

And, by the usual rules of Python functions, default arguments have to come at the end, since (positionally) there's no way to supply later arguments without supplying earlier ones. Now, in a language like Python, theoretically, you can used named arguments to make the above syntax useful, but the Python developers decided to keep things simple (Simple is better than complex, after all) and follow in the C convention of requiring them at the end.

Likewise, they could have reordered the dataclass fields in the constructor so that the default ones end up at the end, but again, they decided to keep it as simple and predictable as possible. And, personally, I think they made the right call. Ruby, for instance, allows default arguments in the middle of a function argument list (not just at the end), and every Ruby style guide I've seen says to avoid that feature like the plague.

  • Related