<h2>Python3.7</h2>
<p>使用<em>默认值</em>参数。</p>
<pre><code>>>> from collections import namedtuple
>>> fields = ('val', 'left', 'right')
>>> Node = namedtuple('Node', fields, defaults=(None,) * len(fields))
>>> Node()
Node(val=None, left=None, right=None)
</code></pre>
<p>或者更好的方法是使用新的<a href="https://docs.python.org/3/library/dataclasses.html" rel="nofollow noreferrer">dataclasses</a>库,它比namedtuple好得多。</p>
<pre><code>>>> from dataclasses import dataclass
>>> from typing import Any
>>> @dataclass
... class Node:
... val: Any = None
... left: 'Node' = None
... right: 'Node' = None
>>> Node()
Node(val=None, left=None, right=None)
</code></pre>
<h2>Python3.7之前</h2>
<p>将<code>Node.__new__.__defaults__</code>设置为默认值。</p>
<pre><code>>>> from collections import namedtuple
>>> Node = namedtuple('Node', 'val left right')
>>> Node.__new__.__defaults__ = (None,) * len(Node._fields)
>>> Node()
Node(val=None, left=None, right=None)
</code></pre>
<h2>Python2.6之前</h2>
<p>将<code>Node.__new__.func_defaults</code>设置为默认值。</p>
<pre><code>>>> from collections import namedtuple
>>> Node = namedtuple('Node', 'val left right')
>>> Node.__new__.func_defaults = (None,) * len(Node._fields)
>>> Node()
Node(val=None, left=None, right=None)
</code></pre>
<h2>命令</h2>
<p>在所有版本的Python中,如果设置的默认值少于namedtuple中的值,则默认值将应用于最右边的参数。这允许您保留一些参数作为必需的参数。</p>
<pre><code>>>> Node.__new__.__defaults__ = (1,2)
>>> Node()
Traceback (most recent call last):
...
TypeError: __new__() missing 1 required positional argument: 'val'
>>> Node(3)
Node(val=3, left=1, right=2)
</code></pre>
<h2>Python2.6到3.6的包装器</h2>
<p>这是一个包装器,它甚至允许您(可选)将默认值设置为<code>None</code>以外的值。这不支持必需的参数。</p>
<pre><code>import collections
def namedtuple_with_defaults(typename, field_names, default_values=()):
T = collections.namedtuple(typename, field_names)
T.__new__.__defaults__ = (None,) * len(T._fields)
if isinstance(default_values, collections.Mapping):
prototype = T(**default_values)
else:
prototype = T(*default_values)
T.__new__.__defaults__ = tuple(prototype)
return T
</code></pre>
<p>示例:</p>
<pre><code>>>> Node = namedtuple_with_defaults('Node', 'val left right')
>>> Node()
Node(val=None, left=None, right=None)
>>> Node = namedtuple_with_defaults('Node', 'val left right', [1, 2, 3])
>>> Node()
Node(val=1, left=2, right=3)
>>> Node = namedtuple_with_defaults('Node', 'val left right', {'right':7})
>>> Node()
Node(val=None, left=None, right=7)
>>> Node(4)
Node(val=4, left=None, right=7)
</code></pre>