4.8. Dataclass Parameters
init
- Generate__init__()
methodrepr
- Generate__repr__()
methodeq
- Generate__eq__()
and__ne__()
methodsorder
- Generate__lt__()
,__le__()
,__gt__()
, and__ge__()
methodsunsafe_hash
- IfFalse
: 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 |
|
|
Generate |
|
|
If |
|
|
Mark all fields as keyword-only |
|
|
Create class with |
4.8.1. SetUp
>>> from dataclasses import dataclass
4.8.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 User:
... firstname: str
... lastname: str
>>>
>>> a = User('Mark', 'Watney')
>>> b = User('Mark', 'Watney')
>>> c = User('Melissa', 'Lewis')
4.8.3. Init
Generate
__init__()
methodDefault:
init=True
>>> @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
4.8.4. Repr
Generate
__repr__()
methodDefault:
repr=True
>>> @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...>
4.8.5. Eq
Generate
__eq__()
and__ne__()
methodsDefault:
eq=True
If
eq=True
compare objects by values (eg. if name is the same in both objects)If
eq=False
compare objects byid()
(eg. if objects are the same, have the same memory address)
>>> @dataclass(eq=True)
... class User:
... firstname: str
... lastname: str
>>>
>>>
>>> a = User('Mark', 'Watney')
>>> b = User('Mark', 'Watney')
>>> c = User('Melissa', 'Lewis')
>>>
>>> a == a
True
>>> a == b
True
>>> a == c
False
>>> @dataclass(eq=False)
... class User:
... firstname: str
... lastname: str
>>>
>>>
>>> a = User('Mark', 'Watney')
>>> b = User('Mark', 'Watney')
>>> c = User('Melissa', 'Lewis')
>>>
>>> a == a
True
>>> a == b
False
>>> a == c
False
4.8.6. Order
Generate
__lt__()
,__le__()
,__gt__()
, and__ge__()
methodsDefault:
order=False
4.8.7. Unsafe_hash
Generate
__hash__()
methodDefault:
unsafe_hash=False
If
False
then the__hash__()
method is generated according to howeq
andfrozen
are set
4.8.8. Match_args
Generate
__match_args__()
methodDefault:
match_args=True
Since 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.
4.8.9. Frozen
Prevents object from modifications
Default:
frozen=False
If
True
then 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'
4.8.10. Kw_only
Mark all fields as keyword-only
Default:
kw_only=False
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.
4.8.11. Slots
Create class with
__slots__
Default:
slots=False
Since Python 3.10
>>> from pprint import pprint
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 User:
... firstname: str
... lastname: str
... __slots__ = ('firstname', 'lastname')
...
... def say_hello(self):
... return f'Hello {self.firstname} {self.lastname}'
...
Traceback (most recent call last):
TypeError: User already specifies __slots__
>>> @dataclass(slots=True)
... class User:
... firstname: str
... lastname: str
...
... def say_hello(self):
... return f'Hello {self.firstname} {self.lastname}'
>>>
>>> pprint(vars(User))
mappingproxy({'__annotations__': {'firstname': <class 'str'>,
'lastname': <class 'str'>},
'__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)},
'__dataclass_params__': _DataclassParams(init=True,repr=True,eq=True,order=False,unsafe_hash=False,frozen=False,match_args=True,kw_only=False,slots=True,weakref_slot=False),
'__doc__': 'User(firstname: str, lastname: str)',
'__eq__': <function User.__eq__ at 0x...>,
'__firstlineno__': 1,
'__hash__': None,
'__init__': <function User.__init__ at 0x...>,
'__match_args__': ('firstname', 'lastname'),
'__module__': '__main__',
'__replace__': <function _replace at 0x...>,
'__repr__': <function User.__repr__ at 0x...>,
'__slots__': ('firstname', 'lastname'),
'__static_attributes__': (),
'firstname': <member 'firstname' of 'User' objects>,
'lastname': <member 'lastname' of 'User' objects>,
'say_hello': <function User.say_hello at 0x...>})
>>>
>>> a = User('Mark', 'Watney')
>>>
>>> a
User(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'}