{"id":2943,"date":"2021-11-15T11:53:37","date_gmt":"2021-11-15T11:53:37","guid":{"rendered":"https:\/\/www.pythontutorial.net\/?page_id=2943"},"modified":"2021-11-15T11:57:32","modified_gmt":"2021-11-15T11:57:32","slug":"python-dataclass","status":"publish","type":"page","link":"https:\/\/www.pythontutorial.net\/python-oop\/python-dataclass\/","title":{"rendered":"Python dataclass"},"content":{"rendered":"\n<p><strong>Summary<\/strong>: in this tutorial, you&#8217;ll learn about the Python dataclass decorator and how to use it effectively.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id='introduction-to-the-python-dataclass'>Introduction to the Python dataclass <a href=\"#introduction-to-the-python-dataclass\" class=\"anchor\" id=\"introduction-to-the-python-dataclass\" title=\"Anchor for Introduction to the Python dataclass\">#<\/a><\/h2>\n\n\n\n<p>Python introduced the dataclass in version 3.7 (<a href=\"https:\/\/www.python.org\/dev\/peps\/pep-0557\/\" target=\"_blank\" rel=\"noreferrer noopener\">PEP 557<\/a>). The dataclass allows you to define <a href=\"https:\/\/www.pythontutorial.net\/python-oop\/python-class\/\">classes<\/a> with less code and more functionality out of the box.<\/p>\n\n\n\n<p>The following defines a regular <code>Person<\/code> class with two instance attributes <code>name<\/code> and <code>age<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Person<\/span>:<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__init__<\/span><span class=\"hljs-params\">(self, name, age)<\/span>:<\/span>\n        self.name = name\n        self.age = age\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>This <code>Person<\/code> class has the <code>__init__<\/code> method that initializes the <code>name<\/code> and <code>age<\/code> attributes. <\/p>\n\n\n\n<p>If you want to have a string representation of the <code>Person<\/code> object, you need to implement the <code><a href=\"https:\/\/www.pythontutorial.net\/python-oop\/python-__str__\/\">__str__<\/a><\/code> or <code><a href=\"https:\/\/www.pythontutorial.net\/python-oop\/python-__repr__\/\">__repr__<\/a><\/code> method. Also, if you want to compare two instances of the <code>Person<\/code> class by an attribute, you need to implement the <a href=\"https:\/\/www.pythontutorial.net\/python-oop\/python-__eq__\/\"><code>__eq__<\/code> <\/a>method.<\/p>\n\n\n\n<p>However, if you use the dataclass, you&#8217;ll have all of these features (and even more) without implementing these dunder methods.<\/p>\n\n\n\n<p>To make the <code>Person<\/code> class a data class, you follow these steps:<\/p>\n\n\n\n<p>First, import the <code>dataclass<\/code> decorator from the <code>dataclasses<\/code> module:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">from<\/span> dataclasses <span class=\"hljs-keyword\">import<\/span> dataclass<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Second, decorate the <code>Person<\/code> class with the <code>dataclass<\/code> decorator and declare the attributes:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-meta\">@dataclass<\/span>\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Person<\/span>:<\/span>\n    name: str\n    age: int<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In this example, the <code>Person<\/code> class has two attributes <code>name<\/code> with the type <code>str<\/code> and <code>age<\/code> with the type <code>int<\/code>. By doing this, the @dataclass decorator implicitly creates the <code>__init__<\/code> method like this:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__init__<\/span><span class=\"hljs-params\">(name: str, age: int)<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Note that the order of the attributes declared in the class will determine the orders of the parameters in the <code>__init__<\/code> method.<\/p>\n\n\n\n<p>And you can create the <code>Person<\/code>&#8216;s object:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">p1 = Person(<span class=\"hljs-string\">'John'<\/span>, <span class=\"hljs-number\">25<\/span>)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>When printing out the <code>Person<\/code>&#8216;s object, you&#8217;ll get a readable format:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">print(p1)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Output:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">Person(name=<span class=\"hljs-string\">'John'<\/span>, age=<span class=\"hljs-number\">25<\/span>)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Also, if you compare two <code>Person<\/code>&#8216;s objects with the same attribute value, it&#8217;ll return <code>True<\/code>. For example:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">p1 = Person(<span class=\"hljs-string\">'John'<\/span>, <span class=\"hljs-number\">25<\/span>)\np2 = Person(<span class=\"hljs-string\">'John'<\/span>, <span class=\"hljs-number\">25<\/span>)\nprint(p1 == p2)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Output:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-literal\">True<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The following discusses other functions that a data class provides.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id='default-values'>Default values <a href=\"#default-values\" class=\"anchor\" id=\"default-values\" title=\"Anchor for Default values\">#<\/a><\/h2>\n\n\n\n<p>When using a regular class, you can define default values for attributes. For example, the following <code>Person<\/code> class has the <code>iq<\/code> parameter with the default value of <code>100<\/code>.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Person<\/span>:<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__init__<\/span><span class=\"hljs-params\">(self, name, age, iq=<span class=\"hljs-number\">100<\/span>)<\/span>:<\/span>\n        self.name = name\n        self.age = age\n        self.iq = iq<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>To define a default value for an attribute in the dataclass, you assign it to the attribute like this:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">from<\/span> dataclasses <span class=\"hljs-keyword\">import<\/span> dataclass\n\n\n<span class=\"hljs-meta\">@dataclass<\/span>\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Person<\/span>:<\/span>\n    name: str\n    age: int\n    iq: int = <span class=\"hljs-number\">100<\/span>\n\n\nprint(Person(<span class=\"hljs-string\">'John Doe'<\/span>, <span class=\"hljs-number\">25<\/span>))<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Like the parameter rules, the attributes with the default values must appear after the ones without default values. Therefore, the following code will not work:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">from<\/span> dataclasses <span class=\"hljs-keyword\">import<\/span> dataclass\n\n\n<span class=\"hljs-meta\">@dataclass<\/span>\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Person<\/span>:<\/span>\n    iq: int = <span class=\"hljs-number\">100<\/span>\n    name: str\n    age: int<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\" id='convert-to-a-tuple-or-a-dictionary'>Convert to a tuple or a dictionary <a href=\"#convert-to-a-tuple-or-a-dictionary\" class=\"anchor\" id=\"convert-to-a-tuple-or-a-dictionary\" title=\"Anchor for Convert to a tuple or a dictionary\">#<\/a><\/h2>\n\n\n\n<p>The <code>dataclasses<\/code> module has the <code>astuple()<\/code> and <code>asdict()<\/code> functions that convert an instance of the dataclass to a <a href=\"https:\/\/www.pythontutorial.net\/python-basics\/python-tuples\/\">tuple<\/a> and a <a href=\"https:\/\/www.pythontutorial.net\/python-basics\/python-dictionary\/\">dictionary<\/a>. For example:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-13\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">from<\/span> dataclasses <span class=\"hljs-keyword\">import<\/span> dataclass, astuple, asdict\n\n\n<span class=\"hljs-meta\">@dataclass<\/span>\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Person<\/span>:<\/span>\n    name: str\n    age: int\n    iq: int = <span class=\"hljs-number\">100<\/span>\n\n\np = Person(<span class=\"hljs-string\">'John Doe'<\/span>, <span class=\"hljs-number\">25<\/span>)\n\nprint(astuple(p))\nprint(asdict(p))<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-13\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Output:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-14\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">(<span class=\"hljs-string\">'John Doe'<\/span>, <span class=\"hljs-number\">25<\/span>, <span class=\"hljs-number\">100<\/span>)\n{<span class=\"hljs-string\">'name'<\/span>: <span class=\"hljs-string\">'John Doe'<\/span>, <span class=\"hljs-string\">'age'<\/span>: <span class=\"hljs-number\">25<\/span>, <span class=\"hljs-string\">'iq'<\/span>: <span class=\"hljs-number\">100<\/span>}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-14\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\" id='create-immutable-objects'>Create immutable objects <a href=\"#create-immutable-objects\" class=\"anchor\" id=\"create-immutable-objects\" title=\"Anchor for Create immutable objects\">#<\/a><\/h2>\n\n\n\n<p>To create readonly objects from a dataclass, you can set the frozen argument of the dataclass decorator to <code>True<\/code>. For example:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-15\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">from<\/span> dataclasses <span class=\"hljs-keyword\">import<\/span> dataclass, astuple, asdict\n\n\n<span class=\"hljs-meta\">@dataclass(frozen=True)<\/span>\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Person<\/span>:<\/span>\n    name: str\n    age: int\n    iq: int = <span class=\"hljs-number\">100<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-15\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>If you attempt to change the attributes of the object after it is created, you&#8217;ll get an error. For example:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-16\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">p = Person(<span class=\"hljs-string\">'Jane Doe'<\/span>, <span class=\"hljs-number\">25<\/span>)\np.iq = <span class=\"hljs-number\">120<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-16\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Error:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-17\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">dataclasses.FrozenInstanceError: cannot assign to field <span class=\"hljs-string\">'iq'<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-17\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\" id='customize-attribute-behaviors'>Customize attribute behaviors <a href=\"#customize-attribute-behaviors\" class=\"anchor\" id=\"customize-attribute-behaviors\" title=\"Anchor for Customize attribute behaviors\">#<\/a><\/h2>\n\n\n\n<p>If don&#8217;t want to initialize an attribute in the __init__ method, you can use the <code>field()<\/code> function from the <code>dataclasses<\/code> module.<\/p>\n\n\n\n<p>The following example defines the <code>can_vote<\/code> attribute that is initialized using the <code>__init__<\/code> method:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-18\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">from<\/span> dataclasses <span class=\"hljs-keyword\">import<\/span> dataclass, field\n\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Person<\/span>:<\/span>\n    name: str\n    age: int\n    iq: int = <span class=\"hljs-number\">100<\/span>\n    can_vote: bool = field(init=<span class=\"hljs-literal\">False<\/span>)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-18\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The <code>field()<\/code> function has multiple interesting parameters such as <code>repr<\/code>, <code>hash<\/code>, <code>compare<\/code>, and <code>metadata<\/code>.<\/p>\n\n\n\n<p>If you want to initialize an attribute that depends on the value of another attribute, you can use the <code>__post_init__<\/code> method. As its name implies, Python calls the <code>__post_init__<\/code> method after the <code>__init__<\/code> method. <\/p>\n\n\n\n<p>The following use the <code>__post_init__<\/code> method to initialize the <code>can_vote<\/code> attribute based on the <code>age<\/code> attribute:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-19\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">from<\/span> dataclasses <span class=\"hljs-keyword\">import<\/span> dataclass, field\n\n\n<span class=\"hljs-meta\">@dataclass<\/span>\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Person<\/span>:<\/span>\n    name: str\n    age: int\n    iq: int = <span class=\"hljs-number\">100<\/span>\n    can_vote: bool = field(init=<span class=\"hljs-literal\">False<\/span>)\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__post_init__<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\n        print(<span class=\"hljs-string\">'called __post_init__ method'<\/span>)\n        self.can_vote = <span class=\"hljs-number\">18<\/span> &lt;= self.age &lt;= <span class=\"hljs-number\">70<\/span>\n\n\np = Person(<span class=\"hljs-string\">'Jane Doe'<\/span>, <span class=\"hljs-number\">25<\/span>)\nprint(p)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-19\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Output:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-20\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">called the __post_init__ method\nPerson(name=<span class=\"hljs-string\">'Jane Doe'<\/span>, age=<span class=\"hljs-number\">25<\/span>, iq=<span class=\"hljs-number\">100<\/span>, can_vote=<span class=\"hljs-literal\">True<\/span>)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-20\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\" id='sort-objects'>Sort objects <a href=\"#sort-objects\" class=\"anchor\" id=\"sort-objects\" title=\"Anchor for Sort objects\">#<\/a><\/h2>\n\n\n\n<p>By default, a dataclass implements the <code>__eq__<\/code> method.<\/p>\n\n\n\n<p>To allow different types of comparisons like <code>__lt__<\/code>, <code>__lte__<\/code>, <code>__gt__<\/code>, <code>__gte__<\/code>, you can set the order argument of the <code>@dataclass<\/code> decorator to True:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-21\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-keyword\">@dataclass<\/span>(order=True)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-21\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>By doing this, the dataclass will sort the objects by every field until it finds a value that&#8217;s not equal. <\/p>\n\n\n\n<p>In practice, you often want to compare objects by a particular attribute, not all attributes. To do that, you need to define a field called <code>sort_index<\/code> and set its value to the attribute that you want to sort.<\/p>\n\n\n\n<p>For example, suppose you have a list of <code>Person<\/code>&#8216;s objects and want to sort them by age:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-22\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">members = &#91;\n    Person(<span class=\"hljs-string\">'John'<\/span>, <span class=\"hljs-number\">25<\/span>),\n    Person(<span class=\"hljs-string\">'Bob'<\/span>, <span class=\"hljs-number\">35<\/span>),\n    Person(<span class=\"hljs-string\">'Alice'<\/span>, <span class=\"hljs-number\">30<\/span>)\n]<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-22\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>To do that, you need to:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>First, pass the <code>order=True<\/code> parameter to the <code>@dataclass<\/code> decorator.<\/li><li>Second, define the <code>sort_index<\/code> attribute and set its <code>init<\/code> parameter to <code>False<\/code>.<\/li><li>Third, set the <code>sort_index<\/code> to the <code>age<\/code> attribute in the <code>__post_init__<\/code> method to sort the <code>Person<\/code>&#8216;s object by age.<\/li><\/ul>\n\n\n\n<p>The following shows the code for sorting <code>Person<\/code>&#8216;s objects by age:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-23\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">from<\/span> dataclasses <span class=\"hljs-keyword\">import<\/span> dataclass, field\n\n\n<span class=\"hljs-meta\">@dataclass(order=True)<\/span>\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Person<\/span>:<\/span>\n    sort_index: int = field(init=<span class=\"hljs-literal\">False<\/span>, repr=<span class=\"hljs-literal\">False<\/span>)\n\n    name: str\n    age: int\n    iq: int = <span class=\"hljs-number\">100<\/span>\n    can_vote: bool = field(init=<span class=\"hljs-literal\">False<\/span>)\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__post_init__<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\n        self.can_vote = <span class=\"hljs-number\">18<\/span> &lt;= self.age &lt;= <span class=\"hljs-number\">70<\/span>\n        <span class=\"hljs-comment\"># sort by age<\/span>\n        self.sort_index = self.age\n\n\nmembers = &#91;\n    Person(name=<span class=\"hljs-string\">'John'<\/span>, age=<span class=\"hljs-number\">25<\/span>),\n    Person(name=<span class=\"hljs-string\">'Bob'<\/span>, age=<span class=\"hljs-number\">35<\/span>),\n    Person(name=<span class=\"hljs-string\">'Alice'<\/span>, age=<span class=\"hljs-number\">30<\/span>)\n]\n\nsorted_members = sorted(members)\n<span class=\"hljs-keyword\">for<\/span> member <span class=\"hljs-keyword\">in<\/span> sorted_members:\n    print(<span class=\"hljs-string\">f'<span class=\"hljs-subst\">{member.name}<\/span>(age=<span class=\"hljs-subst\">{member.age}<\/span>)'<\/span>)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-23\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Output:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-24\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">John(age=<span class=\"hljs-number\">25<\/span>)\nAlice(age=<span class=\"hljs-number\">30<\/span>)\nBob(age=<span class=\"hljs-number\">35<\/span>)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-24\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\" id='summary'>Summary <a href=\"#summary\" class=\"anchor\" id=\"summary\" title=\"Anchor for Summary\">#<\/a><\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li>Use the <code>@dataclass<\/code> decorator from the <code>dataclasses<\/code> module to make a class a dataclass. The dataclass object implements the <code>__eq__<\/code> and <code>__str__<\/code> by default.<\/li><li>Use the <code>astuple()<\/code> and <code>asdict()<\/code> functions to convert an object of a dataclass to a tuple and dictionary.<\/li><li>Use <code>frozen=True<\/code> to define a class whose objects are immutable.<\/li><li>Use <code>__post_init__<\/code> method to initalize attributes that depends on other attributes.<\/li><li>Use <code>sort_index<\/code> to specify the sort attributes of the dataclass objects.<\/li><\/ul>\n<div class=\"helpful-block-content\" data-title=\"\">\n\t<header>\n\t\t<div class=\"wth-question\">Was this tutorial helpful ?<\/div>\n\t\t<div class=\"wth-thumbs\">\n\t\t\t<button\n\t\t\t\tdata-post=\"2943\"\n\t\t\t\tdata-post-url=\"https:\/\/www.pythontutorial.net\/python-oop\/python-dataclass\/\"\n\t\t\t\tdata-post-title=\"Python dataclass\"\n\t\t\t\tdata-response=\"1\"\n\t\t\t\tclass=\"wth-btn-rounded wth-yes-btn\"\n\t\t\t>\n\t\t\t\t<svg\n\t\t\t\t\txmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t\tclass=\"feather feather-thumbs-up block w-full h-full\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\td=\"M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.28a2 2 0 0 0 2-1.7l1.38-9a2 2 0 0 0-2-2.3zM7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3\"\n\t\t\t\t\t><\/path>\n\t\t\t\t<\/svg>\n\t\t\t\t<span class=\"sr-only\"> Yes <\/span>\n\t\t\t<\/button>\n\n\t\t\t<button\n\t\t\t\tdata-response=\"0\"\n\t\t\t\tdata-post=\"2943\"\n\t\t\t\tdata-post-url=\"https:\/\/www.pythontutorial.net\/python-oop\/python-dataclass\/\"\n\t\t\t\tdata-post-title=\"Python dataclass\"\n\t\t\t\tclass=\"wth-btn-rounded wth-no-btn\"\n\t\t\t>\n\t\t\t\t<svg\n\t\t\t\t\txmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\td=\"M10 15v4a3 3 0 0 0 3 3l4-9V2H5.72a2 2 0 0 0-2 1.7l-1.38 9a2 2 0 0 0 2 2.3zm7-13h2.67A2.31 2.31 0 0 1 22 4v7a2.31 2.31 0 0 1-2.33 2H17\"\n\t\t\t\t\t><\/path>\n\t\t\t\t<\/svg>\n\t\t\t\t<span class=\"sr-only\"> No <\/span>\n\t\t\t<\/button>\n\t\t<\/div>\n\t<\/header>\n\n\t<div class=\"wth-form hidden\">\n\t\t<div class=\"wth-form-wrapper\">\n\t\t\t<div class=\"wth-title\"><\/div>\n\t\t\t<textarea class=\"wth-message\"><\/textarea>\n\t\t\t<input type=\"button\" name=\"wth-submit\" class=\"wth-btn wth-btn-submit\" id=\"wth-submit\" \/>\n\t\t\t<input type=\"button\" class=\"wth-btn wth-btn-cancel\" value=\"Cancel\" \/>\n\t\t<\/div>\n\t<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>In this tutorial, you&#8217;ll learn about the Python dataclass decorator and how to use it effectively.<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":417,"menu_order":44,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-2943","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/pages\/2943","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/comments?post=2943"}],"version-history":[{"count":0,"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/pages\/2943\/revisions"}],"up":[{"embeddable":true,"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/pages\/417"}],"wp:attachment":[{"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/media?parent=2943"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}