Shuri2060
Shuri2060

Reputation: 806

Should you decorate dataclass subclasses if not making additional fields

If you don't add any more fields to your subclass is there a need to add the @dataclass decorator to it and would it do anything?

If there is no difference, which is the usual convention?

from dataclasses import dataclass

@dataclass
class AAA:
    x: str
    y: str
    
    ...

# decorate?
class BBB(AAA):
    ...

Upvotes: 5

Views: 939

Answers (2)

Nikolaj Š.
Nikolaj Š.

Reputation: 1986

From documentation, dataclasses source code and experimenting with class instances, I don't see any difference, even if new fields are added to a subclass1.

If we are talking conventions, then I would advise against decorating a subclass. Class BBB's definition is supposed to say "this class behaves just like AAA, but with these changes" (likely a couple of new methods in your case).

Re-decorating BBB:

  • serves no purpose
  • violates DRY principle: although it's just one line, but still there's no particular difference between re-decorating and copy-pasting a short method from superclass
  • could (potentially) get in the way of changing AAA: you might theoretically switch to another library for dataclassing or decide to use @dataclass with non-default parameters, and that'd require maintaining subclass as well (for no good reason).

Update

1 As Andrius corrected me, if you add new fields in a subclass, you'll encounter the following problem:

>>> class BBB(AAA):
...     z: str
... 
>>> BBB('a', 'b', 'c')
Traceback (most recent call last):
  File "<input>", line 1, in <module>
    BBB('a', 'b', 'c')
TypeError: AAA.__init__() takes 3 positional arguments but 4 were given

Original question specifically says that new fields won't be added, so this is just a correction of my initial answer.

Upvotes: 5

anishtain4
anishtain4

Reputation: 2402

If you don't decorate your class, the variables defined in the root of the class will be class attributes which would be shared between all instances of the class. The dataclass let's you define the variables there but they would be instance attributes so each instance can hold its own value. If you instantiate only a single object, you won't see the difference.

UPDATE

Misunderstood your question. The decorate "adds" a few methods to your class, such as __init__ and __repr__. If you're not adding any attributes to your child class, then adding the decorator just instructs the interpreter to go through the MRO to update the mapping, which hasn't changed. It will not cause any trouble, it's just unnecessary. I haven't seen any well-defined convention for it but I wouldn't do it.

Upvotes: 1

Related Questions