It is possible to pass init=False to the decorator on the subclass (and supply your own custom __init__, if necessary):@dataclass
class Foo:
some_default: dict = field(default_factory=dict)@dataclass(init=False) # This works
class Bar(Foo):
other_field: intIvan
--On 23 January 2018 at 03:33, George Leslie-Waksman <waksman@gmail.com> wrote:The proposed implementation of dataclasses prevents defining fields with defaults before fields without defaults. This can create limitations on logical grouping of fields and on inheritance.Take, for example, the case:@dataclassclass Foo:some_default: dict = field(default_factory=dict)@dataclassclass Bar(Foo):other_field: intthis results in the error:5 @dataclass----> 6 class Bar(Foo):7 other_field: int8~/.pyenv/versions/3.6.2/envs/clover_pipeline/lib/python3.6/site-packages/dataclasses.py in dataclass(_cls, init, repr, eq, order, hash, frozen)751752 # We're called as @dataclass, with a class.--> 753 return wrap(_cls)754755~/.pyenv/versions/3.6.2/envs/clover_pipeline/lib/python3.6/site-packages/dataclasses.py in wrap(cls)743744 def wrap(cls):--> 745 return _process_class(cls, repr, eq, order, hash, init, frozen)746747 # See if we're being called as @dataclass or @dataclass().~/.pyenv/versions/3.6.2/envs/clover_pipeline/lib/python3.6/site-packages/dataclasses.py in _process_class(cls, repr, eq, order, hash, init, frozen)675 # in __init__. Use "self" if possible.676 '__dataclass_self__' if 'self' in fields--> 677 else 'self',678 ))679 if repr:~/.pyenv/versions/3.6.2/envs/clover_pipeline/lib/python3.6/site-packages/dataclasses.py in _init_fn(fields, frozen, has_post_init, self_name)422 seen_default = True423 elif seen_default:--> 424 raise TypeError(f'non-default argument {f.name!r} '425 'follows default argument')426TypeError: non-default argument 'other_field' follows default argumentI understand that this is a limitation of positional arguments because the effective __init__ signature is:def __init__(self, some_default: dict = <something>, other_field: int):However, keyword only arguments allow an entirely reasonable solution to this problem:def __init__(self, *, some_default: dict = <something>, other_field: int):And have the added benefit of making the fields in the __init__ call entirely explicit.So, I propose the addition of a keyword_only flag to the @dataclass decorator that renders the __init__ method using keyword only arguments:@dataclass(keyword_only=True)class Bar(Foo):other_field: int--George Leslie-Waksman_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/