769 lines
84 KiB
HTML
769 lines
84 KiB
HTML
|
||
<!DOCTYPE html>
|
||
|
||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<title>dataclasses — Data Classes — Python 3.7.4 documentation</title>
|
||
<link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
|
||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||
|
||
<script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
|
||
<script type="text/javascript" src="../_static/jquery.js"></script>
|
||
<script type="text/javascript" src="../_static/underscore.js"></script>
|
||
<script type="text/javascript" src="../_static/doctools.js"></script>
|
||
<script type="text/javascript" src="../_static/language_data.js"></script>
|
||
|
||
<script type="text/javascript" src="../_static/sidebar.js"></script>
|
||
|
||
<link rel="search" type="application/opensearchdescription+xml"
|
||
title="Search within Python 3.7.4 documentation"
|
||
href="../_static/opensearch.xml"/>
|
||
<link rel="author" title="About these documents" href="../about.html" />
|
||
<link rel="index" title="Index" href="../genindex.html" />
|
||
<link rel="search" title="Search" href="../search.html" />
|
||
<link rel="copyright" title="Copyright" href="../copyright.html" />
|
||
<link rel="next" title="contextlib — Utilities for with-statement contexts" href="contextlib.html" />
|
||
<link rel="prev" title="warnings — Warning control" href="warnings.html" />
|
||
<link rel="shortcut icon" type="image/png" href="../_static/py.png" />
|
||
<link rel="canonical" href="https://docs.python.org/3/library/dataclasses.html" />
|
||
|
||
<script type="text/javascript" src="../_static/copybutton.js"></script>
|
||
<script type="text/javascript" src="../_static/switchers.js"></script>
|
||
|
||
|
||
|
||
<style>
|
||
@media only screen {
|
||
table.full-width-table {
|
||
width: 100%;
|
||
}
|
||
}
|
||
</style>
|
||
|
||
|
||
</head><body>
|
||
|
||
<div class="related" role="navigation" aria-label="related navigation">
|
||
<h3>Navigation</h3>
|
||
<ul>
|
||
<li class="right" style="margin-right: 10px">
|
||
<a href="../genindex.html" title="General Index"
|
||
accesskey="I">index</a></li>
|
||
<li class="right" >
|
||
<a href="../py-modindex.html" title="Python Module Index"
|
||
>modules</a> |</li>
|
||
<li class="right" >
|
||
<a href="contextlib.html" title="contextlib — Utilities for with-statement contexts"
|
||
accesskey="N">next</a> |</li>
|
||
<li class="right" >
|
||
<a href="warnings.html" title="warnings — Warning control"
|
||
accesskey="P">previous</a> |</li>
|
||
<li><img src="../_static/py.png" alt=""
|
||
style="vertical-align: middle; margin-top: -1px"/></li>
|
||
<li><a href="https://www.python.org/">Python</a> »</li>
|
||
<li>
|
||
<span class="language_switcher_placeholder">en</span>
|
||
<span class="version_switcher_placeholder">3.7.4</span>
|
||
<a href="../index.html">Documentation </a> »
|
||
</li>
|
||
|
||
<li class="nav-item nav-item-1"><a href="index.html" >The Python Standard Library</a> »</li>
|
||
<li class="nav-item nav-item-2"><a href="python.html" accesskey="U">Python Runtime Services</a> »</li>
|
||
<li class="right">
|
||
|
||
|
||
<div class="inline-search" style="display: none" role="search">
|
||
<form class="inline-search" action="../search.html" method="get">
|
||
<input placeholder="Quick search" type="text" name="q" />
|
||
<input type="submit" value="Go" />
|
||
<input type="hidden" name="check_keywords" value="yes" />
|
||
<input type="hidden" name="area" value="default" />
|
||
</form>
|
||
</div>
|
||
<script type="text/javascript">$('.inline-search').show(0);</script>
|
||
|
|
||
</li>
|
||
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="document">
|
||
<div class="documentwrapper">
|
||
<div class="bodywrapper">
|
||
<div class="body" role="main">
|
||
|
||
<div class="section" id="module-dataclasses">
|
||
<span id="dataclasses-data-classes"></span><h1><a class="reference internal" href="#module-dataclasses" title="dataclasses: Generate special methods on user-defined classes."><code class="xref py py-mod docutils literal notranslate"><span class="pre">dataclasses</span></code></a> — Data Classes<a class="headerlink" href="#module-dataclasses" title="Permalink to this headline">¶</a></h1>
|
||
<p><strong>Source code:</strong> <a class="reference external" href="https://github.com/python/cpython/tree/3.7/Lib/dataclasses.py">Lib/dataclasses.py</a></p>
|
||
<hr class="docutils" />
|
||
<p>This module provides a decorator and functions for automatically
|
||
adding generated <a class="reference internal" href="../glossary.html#term-special-method"><span class="xref std std-term">special method</span></a>s such as <a class="reference internal" href="../reference/datamodel.html#object.__init__" title="object.__init__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__init__()</span></code></a> and
|
||
<a class="reference internal" href="../reference/datamodel.html#object.__repr__" title="object.__repr__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__repr__()</span></code></a> to user-defined classes. It was originally described
|
||
in <span class="target" id="index-0"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0557"><strong>PEP 557</strong></a>.</p>
|
||
<p>The member variables to use in these generated methods are defined
|
||
using <span class="target" id="index-1"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0526"><strong>PEP 526</strong></a> type annotations. For example this code:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="nd">@dataclass</span>
|
||
<span class="k">class</span> <span class="nc">InventoryItem</span><span class="p">:</span>
|
||
<span class="sd">'''Class for keeping track of an item in inventory.'''</span>
|
||
<span class="n">name</span><span class="p">:</span> <span class="nb">str</span>
|
||
<span class="n">unit_price</span><span class="p">:</span> <span class="nb">float</span>
|
||
<span class="n">quantity_on_hand</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">0</span>
|
||
|
||
<span class="k">def</span> <span class="nf">total_cost</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="nb">float</span><span class="p">:</span>
|
||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">unit_price</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">quantity_on_hand</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Will add, among other things, a <a class="reference internal" href="../reference/datamodel.html#object.__init__" title="object.__init__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__init__()</span></code></a> that looks like:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">unit_price</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span> <span class="n">quantity_on_hand</span><span class="p">:</span> <span class="nb">int</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">unit_price</span> <span class="o">=</span> <span class="n">unit_price</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">quantity_on_hand</span> <span class="o">=</span> <span class="n">quantity_on_hand</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Note that this method is automatically added to the class: it is not
|
||
directly specified in the <code class="docutils literal notranslate"><span class="pre">InventoryItem</span></code> definition shown above.</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">New in version 3.7.</span></p>
|
||
</div>
|
||
<div class="section" id="module-level-decorators-classes-and-functions">
|
||
<h2>Module-level decorators, classes, and functions<a class="headerlink" href="#module-level-decorators-classes-and-functions" title="Permalink to this headline">¶</a></h2>
|
||
<dl class="function">
|
||
<dt id="dataclasses.dataclass">
|
||
<code class="descclassname">@</code><code class="descclassname">dataclasses.</code><code class="descname">dataclass</code><span class="sig-paren">(</span><em>*</em>, <em>init=True</em>, <em>repr=True</em>, <em>eq=True</em>, <em>order=False</em>, <em>unsafe_hash=False</em>, <em>frozen=False</em><span class="sig-paren">)</span><a class="headerlink" href="#dataclasses.dataclass" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>This function is a <a class="reference internal" href="../glossary.html#term-decorator"><span class="xref std std-term">decorator</span></a> that is used to add generated
|
||
<a class="reference internal" href="../glossary.html#term-special-method"><span class="xref std std-term">special method</span></a>s to classes, as described below.</p>
|
||
<p>The <a class="reference internal" href="#dataclasses.dataclass" title="dataclasses.dataclass"><code class="xref py py-func docutils literal notranslate"><span class="pre">dataclass()</span></code></a> decorator examines the class to find
|
||
<code class="docutils literal notranslate"><span class="pre">field</span></code>s. A <code class="docutils literal notranslate"><span class="pre">field</span></code> is defined as class variable that has a
|
||
<a class="reference internal" href="../glossary.html#term-variable-annotation"><span class="xref std std-term">type annotation</span></a>. With two
|
||
exceptions described below, nothing in <a class="reference internal" href="#dataclasses.dataclass" title="dataclasses.dataclass"><code class="xref py py-func docutils literal notranslate"><span class="pre">dataclass()</span></code></a>
|
||
examines the type specified in the variable annotation.</p>
|
||
<p>The order of the fields in all of the generated methods is the
|
||
order in which they appear in the class definition.</p>
|
||
<p>The <a class="reference internal" href="#dataclasses.dataclass" title="dataclasses.dataclass"><code class="xref py py-func docutils literal notranslate"><span class="pre">dataclass()</span></code></a> decorator will add various “dunder” methods to
|
||
the class, described below. If any of the added methods already
|
||
exist on the class, the behavior depends on the parameter, as documented
|
||
below. The decorator returns the same class that is called on; no new
|
||
class is created.</p>
|
||
<p>If <a class="reference internal" href="#dataclasses.dataclass" title="dataclasses.dataclass"><code class="xref py py-func docutils literal notranslate"><span class="pre">dataclass()</span></code></a> is used just as a simple decorator with no parameters,
|
||
it acts as if it has the default values documented in this
|
||
signature. That is, these three uses of <a class="reference internal" href="#dataclasses.dataclass" title="dataclasses.dataclass"><code class="xref py py-func docutils literal notranslate"><span class="pre">dataclass()</span></code></a> are
|
||
equivalent:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="nd">@dataclass</span>
|
||
<span class="k">class</span> <span class="nc">C</span><span class="p">:</span>
|
||
<span class="o">...</span>
|
||
|
||
<span class="nd">@dataclass</span><span class="p">()</span>
|
||
<span class="k">class</span> <span class="nc">C</span><span class="p">:</span>
|
||
<span class="o">...</span>
|
||
|
||
<span class="nd">@dataclass</span><span class="p">(</span><span class="n">init</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="nb">repr</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">eq</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">order</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">unsafe_hash</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">frozen</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
|
||
<span class="k">class</span> <span class="nc">C</span><span class="p">:</span>
|
||
<span class="o">...</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>The parameters to <a class="reference internal" href="#dataclasses.dataclass" title="dataclasses.dataclass"><code class="xref py py-func docutils literal notranslate"><span class="pre">dataclass()</span></code></a> are:</p>
|
||
<ul>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">init</span></code>: If true (the default), a <a class="reference internal" href="../reference/datamodel.html#object.__init__" title="object.__init__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__init__()</span></code></a> method will be
|
||
generated.</p>
|
||
<p>If the class already defines <a class="reference internal" href="../reference/datamodel.html#object.__init__" title="object.__init__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__init__()</span></code></a>, this parameter is
|
||
ignored.</p>
|
||
</li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">repr</span></code>: If true (the default), a <a class="reference internal" href="../reference/datamodel.html#object.__repr__" title="object.__repr__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__repr__()</span></code></a> method will be
|
||
generated. The generated repr string will have the class name and
|
||
the name and repr of each field, in the order they are defined in
|
||
the class. Fields that are marked as being excluded from the repr
|
||
are not included. For example:
|
||
<code class="docutils literal notranslate"><span class="pre">InventoryItem(name='widget',</span> <span class="pre">unit_price=3.0,</span> <span class="pre">quantity_on_hand=10)</span></code>.</p>
|
||
<p>If the class already defines <a class="reference internal" href="../reference/datamodel.html#object.__repr__" title="object.__repr__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__repr__()</span></code></a>, this parameter is
|
||
ignored.</p>
|
||
</li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">eq</span></code>: If true (the default), an <a class="reference internal" href="../reference/datamodel.html#object.__eq__" title="object.__eq__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__eq__()</span></code></a> method will be
|
||
generated. This method compares the class as if it were a tuple
|
||
of its fields, in order. Both instances in the comparison must
|
||
be of the identical type.</p>
|
||
<p>If the class already defines <a class="reference internal" href="../reference/datamodel.html#object.__eq__" title="object.__eq__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__eq__()</span></code></a>, this parameter is
|
||
ignored.</p>
|
||
</li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">order</span></code>: If true (the default is <code class="docutils literal notranslate"><span class="pre">False</span></code>), <a class="reference internal" href="../reference/datamodel.html#object.__lt__" title="object.__lt__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__lt__()</span></code></a>,
|
||
<a class="reference internal" href="../reference/datamodel.html#object.__le__" title="object.__le__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__le__()</span></code></a>, <a class="reference internal" href="../reference/datamodel.html#object.__gt__" title="object.__gt__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__gt__()</span></code></a>, and <a class="reference internal" href="../reference/datamodel.html#object.__ge__" title="object.__ge__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__ge__()</span></code></a> methods will be
|
||
generated. These compare the class as if it were a tuple of its
|
||
fields, in order. Both instances in the comparison must be of the
|
||
identical type. If <code class="docutils literal notranslate"><span class="pre">order</span></code> is true and <code class="docutils literal notranslate"><span class="pre">eq</span></code> is false, a
|
||
<a class="reference internal" href="exceptions.html#ValueError" title="ValueError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">ValueError</span></code></a> is raised.</p>
|
||
<p>If the class already defines any of <a class="reference internal" href="../reference/datamodel.html#object.__lt__" title="object.__lt__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__lt__()</span></code></a>,
|
||
<a class="reference internal" href="../reference/datamodel.html#object.__le__" title="object.__le__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__le__()</span></code></a>, <a class="reference internal" href="../reference/datamodel.html#object.__gt__" title="object.__gt__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__gt__()</span></code></a>, or <a class="reference internal" href="../reference/datamodel.html#object.__ge__" title="object.__ge__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__ge__()</span></code></a>, then
|
||
<a class="reference internal" href="exceptions.html#TypeError" title="TypeError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">TypeError</span></code></a> is raised.</p>
|
||
</li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">unsafe_hash</span></code>: If <code class="docutils literal notranslate"><span class="pre">False</span></code> (the default), a <a class="reference internal" href="../reference/datamodel.html#object.__hash__" title="object.__hash__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__hash__()</span></code></a> method
|
||
is generated according to how <code class="docutils literal notranslate"><span class="pre">eq</span></code> and <code class="docutils literal notranslate"><span class="pre">frozen</span></code> are set.</p>
|
||
<p><a class="reference internal" href="../reference/datamodel.html#object.__hash__" title="object.__hash__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__hash__()</span></code></a> is used by built-in <a class="reference internal" href="functions.html#hash" title="hash"><code class="xref py py-meth docutils literal notranslate"><span class="pre">hash()</span></code></a>, and when objects are
|
||
added to hashed collections such as dictionaries and sets. Having a
|
||
<a class="reference internal" href="../reference/datamodel.html#object.__hash__" title="object.__hash__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__hash__()</span></code></a> implies that instances of the class are immutable.
|
||
Mutability is a complicated property that depends on the programmer’s
|
||
intent, the existence and behavior of <a class="reference internal" href="../reference/datamodel.html#object.__eq__" title="object.__eq__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__eq__()</span></code></a>, and the values of
|
||
the <code class="docutils literal notranslate"><span class="pre">eq</span></code> and <code class="docutils literal notranslate"><span class="pre">frozen</span></code> flags in the <a class="reference internal" href="#dataclasses.dataclass" title="dataclasses.dataclass"><code class="xref py py-func docutils literal notranslate"><span class="pre">dataclass()</span></code></a> decorator.</p>
|
||
<p>By default, <a class="reference internal" href="#dataclasses.dataclass" title="dataclasses.dataclass"><code class="xref py py-func docutils literal notranslate"><span class="pre">dataclass()</span></code></a> will not implicitly add a <a class="reference internal" href="../reference/datamodel.html#object.__hash__" title="object.__hash__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__hash__()</span></code></a>
|
||
method unless it is safe to do so. Neither will it add or change an
|
||
existing explicitly defined <a class="reference internal" href="../reference/datamodel.html#object.__hash__" title="object.__hash__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__hash__()</span></code></a> method. Setting the class
|
||
attribute <code class="docutils literal notranslate"><span class="pre">__hash__</span> <span class="pre">=</span> <span class="pre">None</span></code> has a specific meaning to Python, as
|
||
described in the <a class="reference internal" href="../reference/datamodel.html#object.__hash__" title="object.__hash__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__hash__()</span></code></a> documentation.</p>
|
||
<p>If <a class="reference internal" href="../reference/datamodel.html#object.__hash__" title="object.__hash__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__hash__()</span></code></a> is not explicit defined, or if it is set to <code class="docutils literal notranslate"><span class="pre">None</span></code>,
|
||
then <a class="reference internal" href="#dataclasses.dataclass" title="dataclasses.dataclass"><code class="xref py py-func docutils literal notranslate"><span class="pre">dataclass()</span></code></a> <em>may</em> add an implicit <a class="reference internal" href="../reference/datamodel.html#object.__hash__" title="object.__hash__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__hash__()</span></code></a> method.
|
||
Although not recommended, you can force <a class="reference internal" href="#dataclasses.dataclass" title="dataclasses.dataclass"><code class="xref py py-func docutils literal notranslate"><span class="pre">dataclass()</span></code></a> to create a
|
||
<a class="reference internal" href="../reference/datamodel.html#object.__hash__" title="object.__hash__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__hash__()</span></code></a> method with <code class="docutils literal notranslate"><span class="pre">unsafe_hash=True</span></code>. This might be the case
|
||
if your class is logically immutable but can nonetheless be mutated.
|
||
This is a specialized use case and should be considered carefully.</p>
|
||
<p>Here are the rules governing implicit creation of a <a class="reference internal" href="../reference/datamodel.html#object.__hash__" title="object.__hash__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__hash__()</span></code></a>
|
||
method. Note that you cannot both have an explicit <a class="reference internal" href="../reference/datamodel.html#object.__hash__" title="object.__hash__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__hash__()</span></code></a>
|
||
method in your dataclass and set <code class="docutils literal notranslate"><span class="pre">unsafe_hash=True</span></code>; this will result
|
||
in a <a class="reference internal" href="exceptions.html#TypeError" title="TypeError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">TypeError</span></code></a>.</p>
|
||
<p>If <code class="docutils literal notranslate"><span class="pre">eq</span></code> and <code class="docutils literal notranslate"><span class="pre">frozen</span></code> are both true, by default <a class="reference internal" href="#dataclasses.dataclass" title="dataclasses.dataclass"><code class="xref py py-func docutils literal notranslate"><span class="pre">dataclass()</span></code></a> will
|
||
generate a <a class="reference internal" href="../reference/datamodel.html#object.__hash__" title="object.__hash__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__hash__()</span></code></a> method for you. If <code class="docutils literal notranslate"><span class="pre">eq</span></code> is true and
|
||
<code class="docutils literal notranslate"><span class="pre">frozen</span></code> is false, <a class="reference internal" href="../reference/datamodel.html#object.__hash__" title="object.__hash__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__hash__()</span></code></a> will be set to <code class="docutils literal notranslate"><span class="pre">None</span></code>, marking it
|
||
unhashable (which it is, since it is mutable). If <code class="docutils literal notranslate"><span class="pre">eq</span></code> is false,
|
||
<a class="reference internal" href="../reference/datamodel.html#object.__hash__" title="object.__hash__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__hash__()</span></code></a> will be left untouched meaning the <a class="reference internal" href="../reference/datamodel.html#object.__hash__" title="object.__hash__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__hash__()</span></code></a>
|
||
method of the superclass will be used (if the superclass is
|
||
<a class="reference internal" href="functions.html#object" title="object"><code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></a>, this means it will fall back to id-based hashing).</p>
|
||
</li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">frozen</span></code>: If true (the default is False), assigning to fields will
|
||
generate an exception. This emulates read-only frozen instances. If
|
||
<a class="reference internal" href="../reference/datamodel.html#object.__setattr__" title="object.__setattr__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__setattr__()</span></code></a> or <a class="reference internal" href="../reference/datamodel.html#object.__delattr__" title="object.__delattr__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__delattr__()</span></code></a> is defined in the class, then
|
||
<a class="reference internal" href="exceptions.html#TypeError" title="TypeError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">TypeError</span></code></a> is raised. See the discussion below.</p></li>
|
||
</ul>
|
||
<p><code class="docutils literal notranslate"><span class="pre">field</span></code>s may optionally specify a default value, using normal
|
||
Python syntax:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="nd">@dataclass</span>
|
||
<span class="k">class</span> <span class="nc">C</span><span class="p">:</span>
|
||
<span class="n">a</span><span class="p">:</span> <span class="nb">int</span> <span class="c1"># 'a' has no default value</span>
|
||
<span class="n">b</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">0</span> <span class="c1"># assign a default value for 'b'</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>In this example, both <code class="docutils literal notranslate"><span class="pre">a</span></code> and <code class="docutils literal notranslate"><span class="pre">b</span></code> will be included in the added
|
||
<a class="reference internal" href="../reference/datamodel.html#object.__init__" title="object.__init__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__init__()</span></code></a> method, which will be defined as:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">a</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">b</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">0</span><span class="p">):</span>
|
||
</pre></div>
|
||
</div>
|
||
<p><a class="reference internal" href="exceptions.html#TypeError" title="TypeError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">TypeError</span></code></a> will be raised if a field without a default value
|
||
follows a field with a default value. This is true either when this
|
||
occurs in a single class, or as a result of class inheritance.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="dataclasses.field">
|
||
<code class="descclassname">dataclasses.</code><code class="descname">field</code><span class="sig-paren">(</span><em>*</em>, <em>default=MISSING</em>, <em>default_factory=MISSING</em>, <em>repr=True</em>, <em>hash=None</em>, <em>init=True</em>, <em>compare=True</em>, <em>metadata=None</em><span class="sig-paren">)</span><a class="headerlink" href="#dataclasses.field" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>For common and simple use cases, no other functionality is
|
||
required. There are, however, some dataclass features that
|
||
require additional per-field information. To satisfy this need for
|
||
additional information, you can replace the default field value
|
||
with a call to the provided <a class="reference internal" href="#dataclasses.field" title="dataclasses.field"><code class="xref py py-func docutils literal notranslate"><span class="pre">field()</span></code></a> function. For example:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="nd">@dataclass</span>
|
||
<span class="k">class</span> <span class="nc">C</span><span class="p">:</span>
|
||
<span class="n">mylist</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span> <span class="o">=</span> <span class="n">field</span><span class="p">(</span><span class="n">default_factory</span><span class="o">=</span><span class="nb">list</span><span class="p">)</span>
|
||
|
||
<span class="n">c</span> <span class="o">=</span> <span class="n">C</span><span class="p">()</span>
|
||
<span class="n">c</span><span class="o">.</span><span class="n">mylist</span> <span class="o">+=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">]</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>As shown above, the <code class="docutils literal notranslate"><span class="pre">MISSING</span></code> value is a sentinel object used to
|
||
detect if the <code class="docutils literal notranslate"><span class="pre">default</span></code> and <code class="docutils literal notranslate"><span class="pre">default_factory</span></code> parameters are
|
||
provided. This sentinel is used because <code class="docutils literal notranslate"><span class="pre">None</span></code> is a valid value
|
||
for <code class="docutils literal notranslate"><span class="pre">default</span></code>. No code should directly use the <code class="docutils literal notranslate"><span class="pre">MISSING</span></code>
|
||
value.</p>
|
||
<p>The parameters to <a class="reference internal" href="#dataclasses.field" title="dataclasses.field"><code class="xref py py-func docutils literal notranslate"><span class="pre">field()</span></code></a> are:</p>
|
||
<ul>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">default</span></code>: If provided, this will be the default value for this
|
||
field. This is needed because the <a class="reference internal" href="#dataclasses.field" title="dataclasses.field"><code class="xref py py-meth docutils literal notranslate"><span class="pre">field()</span></code></a> call itself
|
||
replaces the normal position of the default value.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">default_factory</span></code>: If provided, it must be a zero-argument
|
||
callable that will be called when a default value is needed for
|
||
this field. Among other purposes, this can be used to specify
|
||
fields with mutable default values, as discussed below. It is an
|
||
error to specify both <code class="docutils literal notranslate"><span class="pre">default</span></code> and <code class="docutils literal notranslate"><span class="pre">default_factory</span></code>.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">init</span></code>: If true (the default), this field is included as a
|
||
parameter to the generated <a class="reference internal" href="../reference/datamodel.html#object.__init__" title="object.__init__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__init__()</span></code></a> method.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">repr</span></code>: If true (the default), this field is included in the
|
||
string returned by the generated <a class="reference internal" href="../reference/datamodel.html#object.__repr__" title="object.__repr__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__repr__()</span></code></a> method.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">compare</span></code>: If true (the default), this field is included in the
|
||
generated equality and comparison methods (<a class="reference internal" href="../reference/datamodel.html#object.__eq__" title="object.__eq__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__eq__()</span></code></a>,
|
||
<a class="reference internal" href="../reference/datamodel.html#object.__gt__" title="object.__gt__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__gt__()</span></code></a>, et al.).</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">hash</span></code>: This can be a bool or <code class="docutils literal notranslate"><span class="pre">None</span></code>. If true, this field is
|
||
included in the generated <a class="reference internal" href="../reference/datamodel.html#object.__hash__" title="object.__hash__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__hash__()</span></code></a> method. If <code class="docutils literal notranslate"><span class="pre">None</span></code> (the
|
||
default), use the value of <code class="docutils literal notranslate"><span class="pre">compare</span></code>: this would normally be
|
||
the expected behavior. A field should be considered in the hash
|
||
if it’s used for comparisons. Setting this value to anything
|
||
other than <code class="docutils literal notranslate"><span class="pre">None</span></code> is discouraged.</p>
|
||
<p>One possible reason to set <code class="docutils literal notranslate"><span class="pre">hash=False</span></code> but <code class="docutils literal notranslate"><span class="pre">compare=True</span></code>
|
||
would be if a field is expensive to compute a hash value for,
|
||
that field is needed for equality testing, and there are other
|
||
fields that contribute to the type’s hash value. Even if a field
|
||
is excluded from the hash, it will still be used for comparisons.</p>
|
||
</li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">metadata</span></code>: This can be a mapping or None. None is treated as
|
||
an empty dict. This value is wrapped in
|
||
<a class="reference internal" href="types.html#types.MappingProxyType" title="types.MappingProxyType"><code class="xref py py-func docutils literal notranslate"><span class="pre">MappingProxyType()</span></code></a> to make it read-only, and exposed
|
||
on the <a class="reference internal" href="#dataclasses.Field" title="dataclasses.Field"><code class="xref py py-class docutils literal notranslate"><span class="pre">Field</span></code></a> object. It is not used at all by Data
|
||
Classes, and is provided as a third-party extension mechanism.
|
||
Multiple third-parties can each have their own key, to use as a
|
||
namespace in the metadata.</p></li>
|
||
</ul>
|
||
<p>If the default value of a field is specified by a call to
|
||
<a class="reference internal" href="#dataclasses.field" title="dataclasses.field"><code class="xref py py-func docutils literal notranslate"><span class="pre">field()</span></code></a>, then the class attribute for this field will be
|
||
replaced by the specified <code class="docutils literal notranslate"><span class="pre">default</span></code> value. If no <code class="docutils literal notranslate"><span class="pre">default</span></code> is
|
||
provided, then the class attribute will be deleted. The intent is
|
||
that after the <a class="reference internal" href="#dataclasses.dataclass" title="dataclasses.dataclass"><code class="xref py py-func docutils literal notranslate"><span class="pre">dataclass()</span></code></a> decorator runs, the class
|
||
attributes will all contain the default values for the fields, just
|
||
as if the default value itself were specified. For example,
|
||
after:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="nd">@dataclass</span>
|
||
<span class="k">class</span> <span class="nc">C</span><span class="p">:</span>
|
||
<span class="n">x</span><span class="p">:</span> <span class="nb">int</span>
|
||
<span class="n">y</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="n">field</span><span class="p">(</span><span class="nb">repr</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
|
||
<span class="n">z</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="n">field</span><span class="p">(</span><span class="nb">repr</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="mi">10</span><span class="p">)</span>
|
||
<span class="n">t</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">20</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>The class attribute <code class="docutils literal notranslate"><span class="pre">C.z</span></code> will be <code class="docutils literal notranslate"><span class="pre">10</span></code>, the class attribute
|
||
<code class="docutils literal notranslate"><span class="pre">C.t</span></code> will be <code class="docutils literal notranslate"><span class="pre">20</span></code>, and the class attributes <code class="docutils literal notranslate"><span class="pre">C.x</span></code> and
|
||
<code class="docutils literal notranslate"><span class="pre">C.y</span></code> will not be set.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="class">
|
||
<dt id="dataclasses.Field">
|
||
<em class="property">class </em><code class="descclassname">dataclasses.</code><code class="descname">Field</code><a class="headerlink" href="#dataclasses.Field" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p><a class="reference internal" href="#dataclasses.Field" title="dataclasses.Field"><code class="xref py py-class docutils literal notranslate"><span class="pre">Field</span></code></a> objects describe each defined field. These objects
|
||
are created internally, and are returned by the <a class="reference internal" href="#dataclasses.fields" title="dataclasses.fields"><code class="xref py py-func docutils literal notranslate"><span class="pre">fields()</span></code></a>
|
||
module-level method (see below). Users should never instantiate a
|
||
<a class="reference internal" href="#dataclasses.Field" title="dataclasses.Field"><code class="xref py py-class docutils literal notranslate"><span class="pre">Field</span></code></a> object directly. Its documented attributes are:</p>
|
||
<blockquote>
|
||
<div><ul class="simple">
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">name</span></code>: The name of the field.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">type</span></code>: The type of the field.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">default</span></code>, <code class="docutils literal notranslate"><span class="pre">default_factory</span></code>, <code class="docutils literal notranslate"><span class="pre">init</span></code>, <code class="docutils literal notranslate"><span class="pre">repr</span></code>, <code class="docutils literal notranslate"><span class="pre">hash</span></code>,
|
||
<code class="docutils literal notranslate"><span class="pre">compare</span></code>, and <code class="docutils literal notranslate"><span class="pre">metadata</span></code> have the identical meaning and
|
||
values as they do in the <a class="reference internal" href="#dataclasses.field" title="dataclasses.field"><code class="xref py py-func docutils literal notranslate"><span class="pre">field()</span></code></a> declaration.</p></li>
|
||
</ul>
|
||
</div></blockquote>
|
||
<p>Other attributes may exist, but they are private and must not be
|
||
inspected or relied on.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="dataclasses.fields">
|
||
<code class="descclassname">dataclasses.</code><code class="descname">fields</code><span class="sig-paren">(</span><em>class_or_instance</em><span class="sig-paren">)</span><a class="headerlink" href="#dataclasses.fields" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Returns a tuple of <a class="reference internal" href="#dataclasses.Field" title="dataclasses.Field"><code class="xref py py-class docutils literal notranslate"><span class="pre">Field</span></code></a> objects that define the fields for this
|
||
dataclass. Accepts either a dataclass, or an instance of a dataclass.
|
||
Raises <a class="reference internal" href="exceptions.html#TypeError" title="TypeError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">TypeError</span></code></a> if not passed a dataclass or instance of one.
|
||
Does not return pseudo-fields which are <code class="docutils literal notranslate"><span class="pre">ClassVar</span></code> or <code class="docutils literal notranslate"><span class="pre">InitVar</span></code>.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="dataclasses.asdict">
|
||
<code class="descclassname">dataclasses.</code><code class="descname">asdict</code><span class="sig-paren">(</span><em>instance</em>, <em>*</em>, <em>dict_factory=dict</em><span class="sig-paren">)</span><a class="headerlink" href="#dataclasses.asdict" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Converts the dataclass <code class="docutils literal notranslate"><span class="pre">instance</span></code> to a dict (by using the
|
||
factory function <code class="docutils literal notranslate"><span class="pre">dict_factory</span></code>). Each dataclass is converted
|
||
to a dict of its fields, as <code class="docutils literal notranslate"><span class="pre">name:</span> <span class="pre">value</span></code> pairs. dataclasses, dicts,
|
||
lists, and tuples are recursed into. For example:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="nd">@dataclass</span>
|
||
<span class="k">class</span> <span class="nc">Point</span><span class="p">:</span>
|
||
<span class="n">x</span><span class="p">:</span> <span class="nb">int</span>
|
||
<span class="n">y</span><span class="p">:</span> <span class="nb">int</span>
|
||
|
||
<span class="nd">@dataclass</span>
|
||
<span class="k">class</span> <span class="nc">C</span><span class="p">:</span>
|
||
<span class="n">mylist</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">Point</span><span class="p">]</span>
|
||
|
||
<span class="n">p</span> <span class="o">=</span> <span class="n">Point</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="mi">20</span><span class="p">)</span>
|
||
<span class="k">assert</span> <span class="n">asdict</span><span class="p">(</span><span class="n">p</span><span class="p">)</span> <span class="o">==</span> <span class="p">{</span><span class="s1">'x'</span><span class="p">:</span> <span class="mi">10</span><span class="p">,</span> <span class="s1">'y'</span><span class="p">:</span> <span class="mi">20</span><span class="p">}</span>
|
||
|
||
<span class="n">c</span> <span class="o">=</span> <span class="n">C</span><span class="p">([</span><span class="n">Point</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="n">Point</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="mi">4</span><span class="p">)])</span>
|
||
<span class="k">assert</span> <span class="n">asdict</span><span class="p">(</span><span class="n">c</span><span class="p">)</span> <span class="o">==</span> <span class="p">{</span><span class="s1">'mylist'</span><span class="p">:</span> <span class="p">[{</span><span class="s1">'x'</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="s1">'y'</span><span class="p">:</span> <span class="mi">0</span><span class="p">},</span> <span class="p">{</span><span class="s1">'x'</span><span class="p">:</span> <span class="mi">10</span><span class="p">,</span> <span class="s1">'y'</span><span class="p">:</span> <span class="mi">4</span><span class="p">}]}</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Raises <a class="reference internal" href="exceptions.html#TypeError" title="TypeError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">TypeError</span></code></a> if <code class="docutils literal notranslate"><span class="pre">instance</span></code> is not a dataclass instance.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="dataclasses.astuple">
|
||
<code class="descclassname">dataclasses.</code><code class="descname">astuple</code><span class="sig-paren">(</span><em>instance</em>, <em>*</em>, <em>tuple_factory=tuple</em><span class="sig-paren">)</span><a class="headerlink" href="#dataclasses.astuple" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Converts the dataclass <code class="docutils literal notranslate"><span class="pre">instance</span></code> to a tuple (by using the
|
||
factory function <code class="docutils literal notranslate"><span class="pre">tuple_factory</span></code>). Each dataclass is converted
|
||
to a tuple of its field values. dataclasses, dicts, lists, and
|
||
tuples are recursed into.</p>
|
||
<p>Continuing from the previous example:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">assert</span> <span class="n">astuple</span><span class="p">(</span><span class="n">p</span><span class="p">)</span> <span class="o">==</span> <span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="mi">20</span><span class="p">)</span>
|
||
<span class="k">assert</span> <span class="n">astuple</span><span class="p">(</span><span class="n">c</span><span class="p">)</span> <span class="o">==</span> <span class="p">([(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="mi">4</span><span class="p">)],)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Raises <a class="reference internal" href="exceptions.html#TypeError" title="TypeError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">TypeError</span></code></a> if <code class="docutils literal notranslate"><span class="pre">instance</span></code> is not a dataclass instance.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="dataclasses.make_dataclass">
|
||
<code class="descclassname">dataclasses.</code><code class="descname">make_dataclass</code><span class="sig-paren">(</span><em>cls_name</em>, <em>fields</em>, <em>*</em>, <em>bases=()</em>, <em>namespace=None</em>, <em>init=True</em>, <em>repr=True</em>, <em>eq=True</em>, <em>order=False</em>, <em>unsafe_hash=False</em>, <em>frozen=False</em><span class="sig-paren">)</span><a class="headerlink" href="#dataclasses.make_dataclass" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Creates a new dataclass with name <code class="docutils literal notranslate"><span class="pre">cls_name</span></code>, fields as defined
|
||
in <code class="docutils literal notranslate"><span class="pre">fields</span></code>, base classes as given in <code class="docutils literal notranslate"><span class="pre">bases</span></code>, and initialized
|
||
with a namespace as given in <code class="docutils literal notranslate"><span class="pre">namespace</span></code>. <code class="docutils literal notranslate"><span class="pre">fields</span></code> is an
|
||
iterable whose elements are each either <code class="docutils literal notranslate"><span class="pre">name</span></code>, <code class="docutils literal notranslate"><span class="pre">(name,</span> <span class="pre">type)</span></code>,
|
||
or <code class="docutils literal notranslate"><span class="pre">(name,</span> <span class="pre">type,</span> <span class="pre">Field)</span></code>. If just <code class="docutils literal notranslate"><span class="pre">name</span></code> is supplied,
|
||
<code class="docutils literal notranslate"><span class="pre">typing.Any</span></code> is used for <code class="docutils literal notranslate"><span class="pre">type</span></code>. The values of <code class="docutils literal notranslate"><span class="pre">init</span></code>,
|
||
<code class="docutils literal notranslate"><span class="pre">repr</span></code>, <code class="docutils literal notranslate"><span class="pre">eq</span></code>, <code class="docutils literal notranslate"><span class="pre">order</span></code>, <code class="docutils literal notranslate"><span class="pre">unsafe_hash</span></code>, and <code class="docutils literal notranslate"><span class="pre">frozen</span></code> have
|
||
the same meaning as they do in <a class="reference internal" href="#dataclasses.dataclass" title="dataclasses.dataclass"><code class="xref py py-func docutils literal notranslate"><span class="pre">dataclass()</span></code></a>.</p>
|
||
<p>This function is not strictly required, because any Python
|
||
mechanism for creating a new class with <code class="docutils literal notranslate"><span class="pre">__annotations__</span></code> can
|
||
then apply the <a class="reference internal" href="#dataclasses.dataclass" title="dataclasses.dataclass"><code class="xref py py-func docutils literal notranslate"><span class="pre">dataclass()</span></code></a> function to convert that class to
|
||
a dataclass. This function is provided as a convenience. For
|
||
example:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">C</span> <span class="o">=</span> <span class="n">make_dataclass</span><span class="p">(</span><span class="s1">'C'</span><span class="p">,</span>
|
||
<span class="p">[(</span><span class="s1">'x'</span><span class="p">,</span> <span class="nb">int</span><span class="p">),</span>
|
||
<span class="s1">'y'</span><span class="p">,</span>
|
||
<span class="p">(</span><span class="s1">'z'</span><span class="p">,</span> <span class="nb">int</span><span class="p">,</span> <span class="n">field</span><span class="p">(</span><span class="n">default</span><span class="o">=</span><span class="mi">5</span><span class="p">))],</span>
|
||
<span class="n">namespace</span><span class="o">=</span><span class="p">{</span><span class="s1">'add_one'</span><span class="p">:</span> <span class="k">lambda</span> <span class="bp">self</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">x</span> <span class="o">+</span> <span class="mi">1</span><span class="p">})</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Is equivalent to:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="nd">@dataclass</span>
|
||
<span class="k">class</span> <span class="nc">C</span><span class="p">:</span>
|
||
<span class="n">x</span><span class="p">:</span> <span class="nb">int</span>
|
||
<span class="n">y</span><span class="p">:</span> <span class="s1">'typing.Any'</span>
|
||
<span class="n">z</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">5</span>
|
||
|
||
<span class="k">def</span> <span class="nf">add_one</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">x</span> <span class="o">+</span> <span class="mi">1</span>
|
||
</pre></div>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="dataclasses.replace">
|
||
<code class="descclassname">dataclasses.</code><code class="descname">replace</code><span class="sig-paren">(</span><em>instance</em>, <em>**changes</em><span class="sig-paren">)</span><a class="headerlink" href="#dataclasses.replace" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Creates a new object of the same type of <code class="docutils literal notranslate"><span class="pre">instance</span></code>, replacing
|
||
fields with values from <code class="docutils literal notranslate"><span class="pre">changes</span></code>. If <code class="docutils literal notranslate"><span class="pre">instance</span></code> is not a Data
|
||
Class, raises <a class="reference internal" href="exceptions.html#TypeError" title="TypeError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">TypeError</span></code></a>. If values in <code class="docutils literal notranslate"><span class="pre">changes</span></code> do not
|
||
specify fields, raises <a class="reference internal" href="exceptions.html#TypeError" title="TypeError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">TypeError</span></code></a>.</p>
|
||
<p>The newly returned object is created by calling the <a class="reference internal" href="../reference/datamodel.html#object.__init__" title="object.__init__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__init__()</span></code></a>
|
||
method of the dataclass. This ensures that
|
||
<code class="xref py py-meth docutils literal notranslate"><span class="pre">__post_init__()</span></code>, if present, is also called.</p>
|
||
<p>Init-only variables without default values, if any exist, must be
|
||
specified on the call to <a class="reference internal" href="#dataclasses.replace" title="dataclasses.replace"><code class="xref py py-func docutils literal notranslate"><span class="pre">replace()</span></code></a> so that they can be passed to
|
||
<a class="reference internal" href="../reference/datamodel.html#object.__init__" title="object.__init__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__init__()</span></code></a> and <code class="xref py py-meth docutils literal notranslate"><span class="pre">__post_init__()</span></code>.</p>
|
||
<p>It is an error for <code class="docutils literal notranslate"><span class="pre">changes</span></code> to contain any fields that are
|
||
defined as having <code class="docutils literal notranslate"><span class="pre">init=False</span></code>. A <a class="reference internal" href="exceptions.html#ValueError" title="ValueError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">ValueError</span></code></a> will be raised
|
||
in this case.</p>
|
||
<p>Be forewarned about how <code class="docutils literal notranslate"><span class="pre">init=False</span></code> fields work during a call to
|
||
<a class="reference internal" href="#dataclasses.replace" title="dataclasses.replace"><code class="xref py py-func docutils literal notranslate"><span class="pre">replace()</span></code></a>. They are not copied from the source object, but
|
||
rather are initialized in <code class="xref py py-meth docutils literal notranslate"><span class="pre">__post_init__()</span></code>, if they’re
|
||
initialized at all. It is expected that <code class="docutils literal notranslate"><span class="pre">init=False</span></code> fields will
|
||
be rarely and judiciously used. If they are used, it might be wise
|
||
to have alternate class constructors, or perhaps a custom
|
||
<code class="docutils literal notranslate"><span class="pre">replace()</span></code> (or similarly named) method which handles instance
|
||
copying.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="dataclasses.is_dataclass">
|
||
<code class="descclassname">dataclasses.</code><code class="descname">is_dataclass</code><span class="sig-paren">(</span><em>class_or_instance</em><span class="sig-paren">)</span><a class="headerlink" href="#dataclasses.is_dataclass" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Returns True if its parameter is a dataclass or an instance of one,
|
||
otherwise returns False.</p>
|
||
<p>If you need to know if a class is an instance of a dataclass (and
|
||
not a dataclass itself), then add a further check for <code class="docutils literal notranslate"><span class="pre">not</span>
|
||
<span class="pre">isinstance(obj,</span> <span class="pre">type)</span></code>:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">is_dataclass_instance</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span>
|
||
<span class="k">return</span> <span class="n">is_dataclass</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="nb">type</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
</div>
|
||
<div class="section" id="post-init-processing">
|
||
<h2>Post-init processing<a class="headerlink" href="#post-init-processing" title="Permalink to this headline">¶</a></h2>
|
||
<p>The generated <a class="reference internal" href="../reference/datamodel.html#object.__init__" title="object.__init__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__init__()</span></code></a> code will call a method named
|
||
<code class="xref py py-meth docutils literal notranslate"><span class="pre">__post_init__()</span></code>, if <code class="xref py py-meth docutils literal notranslate"><span class="pre">__post_init__()</span></code> is defined on the
|
||
class. It will normally be called as <code class="docutils literal notranslate"><span class="pre">self.__post_init__()</span></code>.
|
||
However, if any <code class="docutils literal notranslate"><span class="pre">InitVar</span></code> fields are defined, they will also be
|
||
passed to <code class="xref py py-meth docutils literal notranslate"><span class="pre">__post_init__()</span></code> in the order they were defined in the
|
||
class. If no <a class="reference internal" href="../reference/datamodel.html#object.__init__" title="object.__init__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__init__()</span></code></a> method is generated, then
|
||
<code class="xref py py-meth docutils literal notranslate"><span class="pre">__post_init__()</span></code> will not automatically be called.</p>
|
||
<p>Among other uses, this allows for initializing field values that
|
||
depend on one or more other fields. For example:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="nd">@dataclass</span>
|
||
<span class="k">class</span> <span class="nc">C</span><span class="p">:</span>
|
||
<span class="n">a</span><span class="p">:</span> <span class="nb">float</span>
|
||
<span class="n">b</span><span class="p">:</span> <span class="nb">float</span>
|
||
<span class="n">c</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="n">field</span><span class="p">(</span><span class="n">init</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
|
||
|
||
<span class="k">def</span> <span class="nf">__post_init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">c</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">a</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">b</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>See the section below on init-only variables for ways to pass
|
||
parameters to <code class="xref py py-meth docutils literal notranslate"><span class="pre">__post_init__()</span></code>. Also see the warning about how
|
||
<a class="reference internal" href="#dataclasses.replace" title="dataclasses.replace"><code class="xref py py-func docutils literal notranslate"><span class="pre">replace()</span></code></a> handles <code class="docutils literal notranslate"><span class="pre">init=False</span></code> fields.</p>
|
||
</div>
|
||
<div class="section" id="class-variables">
|
||
<h2>Class variables<a class="headerlink" href="#class-variables" title="Permalink to this headline">¶</a></h2>
|
||
<p>One of two places where <a class="reference internal" href="#dataclasses.dataclass" title="dataclasses.dataclass"><code class="xref py py-func docutils literal notranslate"><span class="pre">dataclass()</span></code></a> actually inspects the type
|
||
of a field is to determine if a field is a class variable as defined
|
||
in <span class="target" id="index-2"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0526"><strong>PEP 526</strong></a>. It does this by checking if the type of the field is
|
||
<code class="docutils literal notranslate"><span class="pre">typing.ClassVar</span></code>. If a field is a <code class="docutils literal notranslate"><span class="pre">ClassVar</span></code>, it is excluded
|
||
from consideration as a field and is ignored by the dataclass
|
||
mechanisms. Such <code class="docutils literal notranslate"><span class="pre">ClassVar</span></code> pseudo-fields are not returned by the
|
||
module-level <a class="reference internal" href="#dataclasses.fields" title="dataclasses.fields"><code class="xref py py-func docutils literal notranslate"><span class="pre">fields()</span></code></a> function.</p>
|
||
</div>
|
||
<div class="section" id="init-only-variables">
|
||
<h2>Init-only variables<a class="headerlink" href="#init-only-variables" title="Permalink to this headline">¶</a></h2>
|
||
<p>The other place where <a class="reference internal" href="#dataclasses.dataclass" title="dataclasses.dataclass"><code class="xref py py-func docutils literal notranslate"><span class="pre">dataclass()</span></code></a> inspects a type annotation is to
|
||
determine if a field is an init-only variable. It does this by seeing
|
||
if the type of a field is of type <code class="docutils literal notranslate"><span class="pre">dataclasses.InitVar</span></code>. If a field
|
||
is an <code class="docutils literal notranslate"><span class="pre">InitVar</span></code>, it is considered a pseudo-field called an init-only
|
||
field. As it is not a true field, it is not returned by the
|
||
module-level <a class="reference internal" href="#dataclasses.fields" title="dataclasses.fields"><code class="xref py py-func docutils literal notranslate"><span class="pre">fields()</span></code></a> function. Init-only fields are added as
|
||
parameters to the generated <a class="reference internal" href="../reference/datamodel.html#object.__init__" title="object.__init__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__init__()</span></code></a> method, and are passed to
|
||
the optional <code class="xref py py-meth docutils literal notranslate"><span class="pre">__post_init__()</span></code> method. They are not otherwise used
|
||
by dataclasses.</p>
|
||
<p>For example, suppose a field will be initialized from a database, if a
|
||
value is not provided when creating the class:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="nd">@dataclass</span>
|
||
<span class="k">class</span> <span class="nc">C</span><span class="p">:</span>
|
||
<span class="n">i</span><span class="p">:</span> <span class="nb">int</span>
|
||
<span class="n">j</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="kc">None</span>
|
||
<span class="n">database</span><span class="p">:</span> <span class="n">InitVar</span><span class="p">[</span><span class="n">DatabaseType</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||
|
||
<span class="k">def</span> <span class="nf">__post_init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">database</span><span class="p">):</span>
|
||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">j</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">database</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">j</span> <span class="o">=</span> <span class="n">database</span><span class="o">.</span><span class="n">lookup</span><span class="p">(</span><span class="s1">'j'</span><span class="p">)</span>
|
||
|
||
<span class="n">c</span> <span class="o">=</span> <span class="n">C</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="n">database</span><span class="o">=</span><span class="n">my_database</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>In this case, <a class="reference internal" href="#dataclasses.fields" title="dataclasses.fields"><code class="xref py py-func docutils literal notranslate"><span class="pre">fields()</span></code></a> will return <a class="reference internal" href="#dataclasses.Field" title="dataclasses.Field"><code class="xref py py-class docutils literal notranslate"><span class="pre">Field</span></code></a> objects for <code class="docutils literal notranslate"><span class="pre">i</span></code> and
|
||
<code class="docutils literal notranslate"><span class="pre">j</span></code>, but not for <code class="docutils literal notranslate"><span class="pre">database</span></code>.</p>
|
||
</div>
|
||
<div class="section" id="frozen-instances">
|
||
<h2>Frozen instances<a class="headerlink" href="#frozen-instances" title="Permalink to this headline">¶</a></h2>
|
||
<p>It is not possible to create truly immutable Python objects. However,
|
||
by passing <code class="docutils literal notranslate"><span class="pre">frozen=True</span></code> to the <a class="reference internal" href="#dataclasses.dataclass" title="dataclasses.dataclass"><code class="xref py py-meth docutils literal notranslate"><span class="pre">dataclass()</span></code></a> decorator you can
|
||
emulate immutability. In that case, dataclasses will add
|
||
<a class="reference internal" href="../reference/datamodel.html#object.__setattr__" title="object.__setattr__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__setattr__()</span></code></a> and <a class="reference internal" href="../reference/datamodel.html#object.__delattr__" title="object.__delattr__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__delattr__()</span></code></a> methods to the class. These
|
||
methods will raise a <a class="reference internal" href="#dataclasses.FrozenInstanceError" title="dataclasses.FrozenInstanceError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">FrozenInstanceError</span></code></a> when invoked.</p>
|
||
<p>There is a tiny performance penalty when using <code class="docutils literal notranslate"><span class="pre">frozen=True</span></code>:
|
||
<a class="reference internal" href="../reference/datamodel.html#object.__init__" title="object.__init__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__init__()</span></code></a> cannot use simple assignment to initialize fields, and
|
||
must use <a class="reference internal" href="../reference/datamodel.html#object.__setattr__" title="object.__setattr__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">object.__setattr__()</span></code></a>.</p>
|
||
</div>
|
||
<div class="section" id="inheritance">
|
||
<h2>Inheritance<a class="headerlink" href="#inheritance" title="Permalink to this headline">¶</a></h2>
|
||
<p>When the dataclass is being created by the <a class="reference internal" href="#dataclasses.dataclass" title="dataclasses.dataclass"><code class="xref py py-meth docutils literal notranslate"><span class="pre">dataclass()</span></code></a> decorator,
|
||
it looks through all of the class’s base classes in reverse MRO (that
|
||
is, starting at <a class="reference internal" href="functions.html#object" title="object"><code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></a>) and, for each dataclass that it finds,
|
||
adds the fields from that base class to an ordered mapping of fields.
|
||
After all of the base class fields are added, it adds its own fields
|
||
to the ordered mapping. All of the generated methods will use this
|
||
combined, calculated ordered mapping of fields. Because the fields
|
||
are in insertion order, derived classes override base classes. An
|
||
example:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="nd">@dataclass</span>
|
||
<span class="k">class</span> <span class="nc">Base</span><span class="p">:</span>
|
||
<span class="n">x</span><span class="p">:</span> <span class="n">Any</span> <span class="o">=</span> <span class="mf">15.0</span>
|
||
<span class="n">y</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">0</span>
|
||
|
||
<span class="nd">@dataclass</span>
|
||
<span class="k">class</span> <span class="nc">C</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
|
||
<span class="n">z</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">10</span>
|
||
<span class="n">x</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">15</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>The final list of fields is, in order, <code class="docutils literal notranslate"><span class="pre">x</span></code>, <code class="docutils literal notranslate"><span class="pre">y</span></code>, <code class="docutils literal notranslate"><span class="pre">z</span></code>. The final
|
||
type of <code class="docutils literal notranslate"><span class="pre">x</span></code> is <code class="docutils literal notranslate"><span class="pre">int</span></code>, as specified in class <code class="docutils literal notranslate"><span class="pre">C</span></code>.</p>
|
||
<p>The generated <a class="reference internal" href="../reference/datamodel.html#object.__init__" title="object.__init__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__init__()</span></code></a> method for <code class="docutils literal notranslate"><span class="pre">C</span></code> will look like:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">15</span><span class="p">,</span> <span class="n">y</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">z</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">10</span><span class="p">):</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="section" id="default-factory-functions">
|
||
<h2>Default factory functions<a class="headerlink" href="#default-factory-functions" title="Permalink to this headline">¶</a></h2>
|
||
<blockquote>
|
||
<div><p>If a <a class="reference internal" href="#dataclasses.field" title="dataclasses.field"><code class="xref py py-func docutils literal notranslate"><span class="pre">field()</span></code></a> specifies a <code class="docutils literal notranslate"><span class="pre">default_factory</span></code>, it is called with
|
||
zero arguments when a default value for the field is needed. For
|
||
example, to create a new instance of a list, use:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">mylist</span><span class="p">:</span> <span class="nb">list</span> <span class="o">=</span> <span class="n">field</span><span class="p">(</span><span class="n">default_factory</span><span class="o">=</span><span class="nb">list</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>If a field is excluded from <a class="reference internal" href="../reference/datamodel.html#object.__init__" title="object.__init__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__init__()</span></code></a> (using <code class="docutils literal notranslate"><span class="pre">init=False</span></code>)
|
||
and the field also specifies <code class="docutils literal notranslate"><span class="pre">default_factory</span></code>, then the default
|
||
factory function will always be called from the generated
|
||
<a class="reference internal" href="../reference/datamodel.html#object.__init__" title="object.__init__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__init__()</span></code></a> function. This happens because there is no other
|
||
way to give the field an initial value.</p>
|
||
</div></blockquote>
|
||
</div>
|
||
<div class="section" id="mutable-default-values">
|
||
<h2>Mutable default values<a class="headerlink" href="#mutable-default-values" title="Permalink to this headline">¶</a></h2>
|
||
<blockquote>
|
||
<div><p>Python stores default member variable values in class attributes.
|
||
Consider this example, not using dataclasses:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">C</span><span class="p">:</span>
|
||
<span class="n">x</span> <span class="o">=</span> <span class="p">[]</span>
|
||
<span class="k">def</span> <span class="nf">add</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">element</span><span class="p">):</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">x</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">element</span><span class="p">)</span>
|
||
|
||
<span class="n">o1</span> <span class="o">=</span> <span class="n">C</span><span class="p">()</span>
|
||
<span class="n">o2</span> <span class="o">=</span> <span class="n">C</span><span class="p">()</span>
|
||
<span class="n">o1</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
|
||
<span class="n">o2</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
|
||
<span class="k">assert</span> <span class="n">o1</span><span class="o">.</span><span class="n">x</span> <span class="o">==</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">]</span>
|
||
<span class="k">assert</span> <span class="n">o1</span><span class="o">.</span><span class="n">x</span> <span class="ow">is</span> <span class="n">o2</span><span class="o">.</span><span class="n">x</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Note that the two instances of class <code class="docutils literal notranslate"><span class="pre">C</span></code> share the same class
|
||
variable <code class="docutils literal notranslate"><span class="pre">x</span></code>, as expected.</p>
|
||
<p>Using dataclasses, <em>if</em> this code was valid:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="nd">@dataclass</span>
|
||
<span class="k">class</span> <span class="nc">D</span><span class="p">:</span>
|
||
<span class="n">x</span><span class="p">:</span> <span class="n">List</span> <span class="o">=</span> <span class="p">[]</span>
|
||
<span class="k">def</span> <span class="nf">add</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">element</span><span class="p">):</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">x</span> <span class="o">+=</span> <span class="n">element</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>it would generate code similar to:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">D</span><span class="p">:</span>
|
||
<span class="n">x</span> <span class="o">=</span> <span class="p">[]</span>
|
||
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x</span><span class="o">=</span><span class="n">x</span><span class="p">):</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">x</span> <span class="o">=</span> <span class="n">x</span>
|
||
<span class="k">def</span> <span class="nf">add</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">element</span><span class="p">):</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">x</span> <span class="o">+=</span> <span class="n">element</span>
|
||
|
||
<span class="k">assert</span> <span class="n">D</span><span class="p">()</span><span class="o">.</span><span class="n">x</span> <span class="ow">is</span> <span class="n">D</span><span class="p">()</span><span class="o">.</span><span class="n">x</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>This has the same issue as the original example using class <code class="docutils literal notranslate"><span class="pre">C</span></code>.
|
||
That is, two instances of class <code class="docutils literal notranslate"><span class="pre">D</span></code> that do not specify a value for
|
||
<code class="docutils literal notranslate"><span class="pre">x</span></code> when creating a class instance will share the same copy of
|
||
<code class="docutils literal notranslate"><span class="pre">x</span></code>. Because dataclasses just use normal Python class creation
|
||
they also share this behavior. There is no general way for Data
|
||
Classes to detect this condition. Instead, dataclasses will raise a
|
||
<a class="reference internal" href="exceptions.html#TypeError" title="TypeError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">TypeError</span></code></a> if it detects a default parameter of type <code class="docutils literal notranslate"><span class="pre">list</span></code>,
|
||
<code class="docutils literal notranslate"><span class="pre">dict</span></code>, or <code class="docutils literal notranslate"><span class="pre">set</span></code>. This is a partial solution, but it does protect
|
||
against many common errors.</p>
|
||
<p>Using default factory functions is a way to create new instances of
|
||
mutable types as default values for fields:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="nd">@dataclass</span>
|
||
<span class="k">class</span> <span class="nc">D</span><span class="p">:</span>
|
||
<span class="n">x</span><span class="p">:</span> <span class="nb">list</span> <span class="o">=</span> <span class="n">field</span><span class="p">(</span><span class="n">default_factory</span><span class="o">=</span><span class="nb">list</span><span class="p">)</span>
|
||
|
||
<span class="k">assert</span> <span class="n">D</span><span class="p">()</span><span class="o">.</span><span class="n">x</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">D</span><span class="p">()</span><span class="o">.</span><span class="n">x</span>
|
||
</pre></div>
|
||
</div>
|
||
</div></blockquote>
|
||
</div>
|
||
<div class="section" id="exceptions">
|
||
<h2>Exceptions<a class="headerlink" href="#exceptions" title="Permalink to this headline">¶</a></h2>
|
||
<dl class="exception">
|
||
<dt id="dataclasses.FrozenInstanceError">
|
||
<em class="property">exception </em><code class="descclassname">dataclasses.</code><code class="descname">FrozenInstanceError</code><a class="headerlink" href="#dataclasses.FrozenInstanceError" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Raised when an implicitly defined <a class="reference internal" href="../reference/datamodel.html#object.__setattr__" title="object.__setattr__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__setattr__()</span></code></a> or
|
||
<a class="reference internal" href="../reference/datamodel.html#object.__delattr__" title="object.__delattr__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__delattr__()</span></code></a> is called on a dataclass which was defined with
|
||
<code class="docutils literal notranslate"><span class="pre">frozen=True</span></code>.</p>
|
||
</dd></dl>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||
<div class="sphinxsidebarwrapper">
|
||
<h3><a href="../contents.html">Table of Contents</a></h3>
|
||
<ul>
|
||
<li><a class="reference internal" href="#"><code class="xref py py-mod docutils literal notranslate"><span class="pre">dataclasses</span></code> — Data Classes</a><ul>
|
||
<li><a class="reference internal" href="#module-level-decorators-classes-and-functions">Module-level decorators, classes, and functions</a></li>
|
||
<li><a class="reference internal" href="#post-init-processing">Post-init processing</a></li>
|
||
<li><a class="reference internal" href="#class-variables">Class variables</a></li>
|
||
<li><a class="reference internal" href="#init-only-variables">Init-only variables</a></li>
|
||
<li><a class="reference internal" href="#frozen-instances">Frozen instances</a></li>
|
||
<li><a class="reference internal" href="#inheritance">Inheritance</a></li>
|
||
<li><a class="reference internal" href="#default-factory-functions">Default factory functions</a></li>
|
||
<li><a class="reference internal" href="#mutable-default-values">Mutable default values</a></li>
|
||
<li><a class="reference internal" href="#exceptions">Exceptions</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
|
||
<h4>Previous topic</h4>
|
||
<p class="topless"><a href="warnings.html"
|
||
title="previous chapter"><code class="xref py py-mod docutils literal notranslate"><span class="pre">warnings</span></code> — Warning control</a></p>
|
||
<h4>Next topic</h4>
|
||
<p class="topless"><a href="contextlib.html"
|
||
title="next chapter"><code class="xref py py-mod docutils literal notranslate"><span class="pre">contextlib</span></code> — Utilities for <code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code>-statement contexts</a></p>
|
||
<div role="note" aria-label="source link">
|
||
<h3>This Page</h3>
|
||
<ul class="this-page-menu">
|
||
<li><a href="../bugs.html">Report a Bug</a></li>
|
||
<li>
|
||
<a href="https://github.com/python/cpython/blob/3.7/Doc/library/dataclasses.rst"
|
||
rel="nofollow">Show Source
|
||
</a>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="clearer"></div>
|
||
</div>
|
||
<div class="related" role="navigation" aria-label="related navigation">
|
||
<h3>Navigation</h3>
|
||
<ul>
|
||
<li class="right" style="margin-right: 10px">
|
||
<a href="../genindex.html" title="General Index"
|
||
>index</a></li>
|
||
<li class="right" >
|
||
<a href="../py-modindex.html" title="Python Module Index"
|
||
>modules</a> |</li>
|
||
<li class="right" >
|
||
<a href="contextlib.html" title="contextlib — Utilities for with-statement contexts"
|
||
>next</a> |</li>
|
||
<li class="right" >
|
||
<a href="warnings.html" title="warnings — Warning control"
|
||
>previous</a> |</li>
|
||
<li><img src="../_static/py.png" alt=""
|
||
style="vertical-align: middle; margin-top: -1px"/></li>
|
||
<li><a href="https://www.python.org/">Python</a> »</li>
|
||
<li>
|
||
<span class="language_switcher_placeholder">en</span>
|
||
<span class="version_switcher_placeholder">3.7.4</span>
|
||
<a href="../index.html">Documentation </a> »
|
||
</li>
|
||
|
||
<li class="nav-item nav-item-1"><a href="index.html" >The Python Standard Library</a> »</li>
|
||
<li class="nav-item nav-item-2"><a href="python.html" >Python Runtime Services</a> »</li>
|
||
<li class="right">
|
||
|
||
|
||
<div class="inline-search" style="display: none" role="search">
|
||
<form class="inline-search" action="../search.html" method="get">
|
||
<input placeholder="Quick search" type="text" name="q" />
|
||
<input type="submit" value="Go" />
|
||
<input type="hidden" name="check_keywords" value="yes" />
|
||
<input type="hidden" name="area" value="default" />
|
||
</form>
|
||
</div>
|
||
<script type="text/javascript">$('.inline-search').show(0);</script>
|
||
|
|
||
</li>
|
||
|
||
</ul>
|
||
</div>
|
||
<div class="footer">
|
||
© <a href="../copyright.html">Copyright</a> 2001-2019, Python Software Foundation.
|
||
<br />
|
||
The Python Software Foundation is a non-profit corporation.
|
||
<a href="https://www.python.org/psf/donations/">Please donate.</a>
|
||
<br />
|
||
Last updated on Jul 13, 2019.
|
||
<a href="../bugs.html">Found a bug</a>?
|
||
<br />
|
||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 2.0.1.
|
||
</div>
|
||
|
||
</body>
|
||
</html> |