Consider:
from dataclasses import dataclass, field
@dataclass
class Example:
a: int
b: int = 2
c: int = field(default=3)
d: int = field(default_factory=lambda: 4)
To my surprise, Example.b
and Example.c
exist, while Example.a
and Example.d
don't (yes, I am talking about the class attributes here, not instance attributes):
try:
print(Example.a)
except AttributeError as e:
print(e)
# AttributeError: type object 'Example' has no attribute 'a'
print(Example.b)
# 2
print(Example.c)
# 3
try:
print(Example.d)
except AttributeError as e:
print(e)
# AttributeError: type object 'Example' has no attribute 'd'
I expected all of them to give an error. What I want is instance attributes, not class attributes. The fact that sometimes a class attribute also exists seems like a door for bugs.
Obviously, from what I learned above, I can just do the following:
from dataclasses import dataclass, field
@dataclass
class Example:
a: int
b: int = field(default_factory=lambda: 2)
c: int = field(default_factory=lambda: 3)
d: int = field(default_factory=lambda: 4)
Questions:
1. Is there a cleaner way of achieving this? Is this usage of default_factory
considered unreadable?
2. Why would anyone want a field that is both a class attribute and an instance attribute?
Thanks!