+-

我正在尝试将一个冗长的空洞“数据”类转换为一个命名元组.我的班级目前看起来像这样:
class Node(object):
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
转换为namedtuple后,它看起来像:
from collections import namedtuple
Node = namedtuple('Node', 'val left right')
但这里有一个问题.我的原始类允许我传入一个值,并使用命名/关键字参数的默认值来处理默认值.就像是:
class BinaryTree(object):
def __init__(self, val):
self.root = Node(val)
但是这对我重构的名为元组的情况不起作用,因为它希望我传递所有字段.我当然可以将Node(val)的出现替换为Node(val,None,None),但这不符合我的喜好.
那么有没有一个好的技巧可以让我的重写成功而不会增加很多代码复杂性(元编程)或者我应该吞下药丸并继续“搜索和替换”? 🙂
最佳答案
Python 3.7
使用defaults参数.
>>> from collections import namedtuple
>>> fields = ('val', 'left', 'right')
>>> Node = namedtuple('Node', fields, defaults=(None,) * len(fields))
>>> Node()
Node(val=None, left=None, right=None)
在Python 3.7之前
将Node .__ new __.__ defaults__设置为默认值.
>>> 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)
在Python 2.6之前
将Node .__ new __.func_defaults设置为默认值.
>>> 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)
订购
在所有版本的Python中,如果您设置的默认值少于namedtuple中存在的默认值,则默认值将应用于最右侧的参数.这允许您将一些参数保留为必需参数.
>>> 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)
Python 2.6到3.6的包装器
这是你的包装器,甚至可以让你(可选)将默认值设置为None以外的其他值.这不支持必需的参数.
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
例:
>>> 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)
点击查看更多相关文章
转载注明原文:python – namedtuple和可选关键字参数的默认值 - 乐贴网