python - namedtuple and optional keyword arguments -
i'm trying convert longish hollow "data" class named tuple. class looks this:
class node(object): def __init__(self, val, left=none, right=none): self.val = val self.left = left self.right = right
after conversion namedtuple
looks like:
from collections import namedtuple node = namedtuple('node', 'val left right')
but there problem here. original class allowed me pass in value , took care of default using default values named/keyword arguments. like:
class binarytree(object): def __init__(self, val): self.root = node(val)
but doesn't work in case of refactored named tuple since expects me pass fields. can of course replace occurrences of node(val)
node(val, none, none)
isn't liking.
so there exist trick can make re-write successful without adding lot of code complexity (metaprogramming) or should swallow pill , go ahead "search , replace"? :)
set node.__new__.__defaults__
(or node.__new__.func_defaults
before python 2.6) default values.
>>> collections import namedtuple >>> node = namedtuple('node', 'val left right') >>> node.__new__.__defaults__ = (none,) * len(node._fields) >>> node() node(val=none, left=none, right=none)
you can have required fields making __defaults__
list shorter.
>>> node.__new__.__defaults__ = (none, none) >>> node() traceback (most recent call last): ... typeerror: __new__() missing 1 required positional argument: 'val' >>> node(3) node(val=3, left=none, right=none)
wrapper
here's nice wrapper you, lets (optionally) set default values other none
. (this not support required arguments.):
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
example:
>>> 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)
Comments
Post a Comment