7.10. Dataclass Parameters¶
init
- Generate__init__()
methodrepr
- Generate__repr__()
methodeq
- Generate__eq__()
and__ne__()
methodsorder
- Generate__lt__()
,__le__()
,__gt__()
, and__ge__()
methodsunsafe_hash
- If False: the__hash__()
method is generated according to how eq and frozen are setfrozen
- IfTrue
: assigning to fields will generate an exceptionmatch_args
- Generate__match_args__()
methodkw_only
- Mark all fields as keyword-onlyslots
- Create class with__slots__
Option |
Default |
Description (if True) |
---|---|---|
|
|
Generate |
|
|
Generate |
|
|
Generate |
|
|
Generate |
|
|
If False: the |
|
|
If |
|
|
Generate |
|
|
Mark all fields as keyword-only |
|
|
Create class with |
7.10.1. SetUp¶
>>> from dataclasses import dataclass
7.10.2. Example¶
>>> @dataclass(init=True, repr=True, eq=True, order=False, unsafe_hash=False,
... frozen=False, match_args=True, kw_only=False, slots=False)
... class Astronaut:
... firstname: str
... lastname: str
>>>
>>> astro1 = Astronaut('Mark', 'Watney')
>>> astro2 = Astronaut('Mark', 'Watney')
>>> astro3 = Astronaut('Melissa', 'Lewis')
7.10.3. Init¶
init=True
by defaultGenerate
__init__()
method
>>> @dataclass(init=True)
... class Point:
... x: int
... y: int
>>>
>>>
>>> p = Point(10, 20)
>>>
>>> print(p)
Point(x=10, y=20)
>>> @dataclass(init=False)
... class Point:
... x: int
... y: int
>>>
>>>
>>> p = Point(10, 20)
Traceback (most recent call last):
TypeError: Point() takes no arguments
7.10.4. Repr¶
repr=True
by defaultGenerate
__repr__()
for pretty printing
>>> @dataclass(repr=True)
... class Point:
... x: int
... y: int
>>>
>>>
>>> p = Point(10, 20)
>>>
>>> print(p)
Point(x=10, y=20)
>>> @dataclass(repr=False)
... class Point:
... x: int
... y: int
>>>
>>>
>>> p = Point(10, 20)
>>>
>>> print(p)
<__main__.Point object at 0x...>
7.10.5. Frozen¶
frozen=False
by defaultPrevents object from modifications
Assigning to fields will generate an exception
>>> @dataclass(frozen=False)
... class Point:
... x: int
... y: int
>>>
>>>
>>> p = Point(10, 20)
>>> p.x = 30
>>>
>>> print(p)
Point(x=30, y=20)
>>> @dataclass(frozen=True)
... class Point:
... x: int
... y: int
>>>
>>>
>>> p = Point(10, 20)
>>> p.x = 30
Traceback (most recent call last):
dataclasses.FrozenInstanceError: cannot assign to field 'x'
7.10.6. Eq¶
eq=True
by defaultwhen
eq=False
compare objects byid()
not valueswhen
eq=True
compare objects by value notid()
>>> @dataclass(eq=True)
... class Astronaut:
... firstname: str
... lastname: str
>>>
>>>
>>> astro1 = Astronaut('Mark', 'Watney')
>>> astro2 = Astronaut('Mark', 'Watney')
>>> astro3 = Astronaut('Melissa', 'Lewis')
>>>
>>> astro1 == astro1
True
>>> astro1 == astro2
True
>>> astro1 == astro3
False
>>>
>>> astro1 != astro1
False
>>> astro1 != astro2
False
>>> astro1 != astro3
True
>>> @dataclass(eq=False)
... class Astronaut:
... firstname: str
... lastname: str
>>>
>>>
>>> astro1 = Astronaut('Mark', 'Watney')
>>> astro2 = Astronaut('Mark', 'Watney')
>>> astro3 = Astronaut('Melissa', 'Lewis')
>>>
>>> astro1 == astro1
True
>>> astro1 == astro2
False
>>> astro1 == astro3
False
>>>
>>> astro1 != astro1
False
>>> astro1 != astro2
True
>>> astro1 != astro3
True
7.10.7. Hash¶
hash=False
by defaultthe
__hash__()
method is generated according to how eq and frozen are set
7.10.8. Order¶
order=False
by defaultGenerate
__lt__()
,__le__()
,__gt__()
, and__ge__()
methods
7.10.9. Match_args¶
match_args=True
by defaultSince Python 3.10
If true, the __match_args__ tuple will be created from the list of parameters to the generated __init__() method (even if __init__() is not generated, see above). If false, or if __match_args__ is already defined in the class, then __match_args__ will not be generated. New in version 3.10.
7.10.10. Kw_only¶
kw_only=False
by defaultMark all fields as keyword-only
Since Python 3.10
If true, then all fields will be marked as keyword-only. If a field is marked as keyword-only, then the only affect is that the __init__() parameter generated from a keyword-only field must be specified with a keyword when __init__() is called. There is no effect on any other aspect of dataclasses.
7.10.11. Slots¶
slots=False
by defaultCreate class with
__slots__
Since Python 3.10
If true, __slots__ attribute will be generated and new class will be returned instead of the original one. If __slots__ is already defined in the class, then TypeError is raised.
>>> @dataclass(slots=True)
... class Astronaut:
... firstname: str
... lastname: str
... __slots__ = ('firstname', 'lastname')
...
... def say_hello(self):
... return f'Hello {self.firstname} {self.lastname}'
...
Traceback (most recent call last):
TypeError: Astronaut already specifies __slots__
>>> @dataclass(slots=True)
... class Astronaut:
... firstname: str
... lastname: str
...
... def say_hello(self):
... return f'Hello {self.firstname} {self.lastname}'
>>>
>>> vars(Astronaut)
mappingproxy({'__module__': '__main__',
'__annotations__': {'firstname': <class 'str'>, 'lastname': <class 'str'>},
'say_hello': <function Astronaut.say_hello at 0x...>,
'__weakref__': <attribute '__weakref__' of 'Astronaut' objects>,
'__doc__': 'Astronaut(firstname: str, lastname: str)',
'__dataclass_params__': _DataclassParams(init=True,repr=True,eq=True,order=False,unsafe_hash=False,frozen=False),
'__dataclass_fields__': {'firstname': Field(name='firstname',type=<class 'str'>,default=<dataclasses._MISSING_TYPE object at 0x...>,default_factory=<dataclasses._MISSING_TYPE object at 0x...>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),kw_only=False,_field_type=_FIELD),
'lastname': Field(name='lastname',type=<class 'str'>,default=<dataclasses._MISSING_TYPE object at 0x...>,default_factory=<dataclasses._MISSING_TYPE object at 0x...>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),kw_only=False,_field_type=_FIELD)},
'__init__': <function Astronaut.__init__ at 0x...>,
'__repr__': <function Astronaut.__repr__ at 0x...>,
'__eq__': <function Astronaut.__eq__ at 0x...>,
'__hash__': None,
'__match_args__': ('firstname', 'lastname'),
'__slots__': ('firstname', 'lastname'),
'firstname': <member 'firstname' of 'Astronaut' objects>,
'lastname': <member 'lastname' of 'Astronaut' objects>})
>>>
>>> a = Astronaut('Mark', 'Watney')
>>>
>>> a
Astronaut(firstname='Mark', lastname='Watney')
>>>
>>> vars(a)
Traceback (most recent call last):
TypeError: vars() argument must have __dict__ attribute
>>>
>>> a.__slots__
('firstname', 'lastname')
>>>
>>> {attrname: getattr(a, attrname) for attrname in a.__slots__}
{'firstname': 'Mark', 'lastname': 'Watney'}