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

Popular posts from this blog

Is there a better way to structure post methods in Class Based Views -

performance - Why is XCHG reg, reg a 3 micro-op instruction on modern Intel architectures? -

jquery - Responsive Navbar with Sub Navbar -