python - correctly overloading the __add__ of a namedtuple -


i'm trying overload __add__ method on namedtuple instances , i'm having bit of trouble.

the parameters input namedtuples dynamically generated. 4 parameters same , in same order, rest can , in number. need able dynamically define namedtuple class factory. , after create several instances, i'd able add them new namedtuple instance, unique parameters together. having trouble overloading __add__ method. doesn't seem work.

so example, if have 3 namedtuple instances

e = row(a=1, b=2, c=3, d=4) m = row(a=1, b=2, c=3, d=4, param1='a', param2='b') t = row(a=1, b=2, c=3, d=4, param3='val', param4=10) 

i'd able add them e + m + t returns

row(a=1, b=2, c=3, d=4, param1='a', param2='b', param3='val', param4=10)

here current code

class row(object):     ''' creates new namedtuple object '''     __slots__ = ()      def __new__(cls, *args, **kwargs):         ''' make new row instance '''         default = namedtuple('row', 'a, b, c, d')         newcols = set(args) - set(default._fields)         finalfields = default._fields + tuple(newcols) if newcols else default._fields         return namedtuple('row', finalfields)      def __add__(self, other):         ''' new add '''         self_dict = self._asdict()         other_dict = other._asdict()         self_dict.update(other_dict)         new_fields = tuple(self_dict.keys())         new_row = namedtuple('row', new_fields)         return new_row(**self_dict) 

with this, can correctly dynamically generate new namedtuples, , instantiate them

e = row() m = row(*['a', 'b', 'c', 'd', 'param1', 'param2'])  e._fields ('a', 'b', 'c', 'd') m._fields ('a', 'b', 'c', 'd', 'param1', 'param2')  e2 = e(1, 2, 3, 4) m2 = m(1, 2, 3, 4, 'a', 'b')  e2 row(a=1, b=2, c=3, d=4) type(e2) __main__.row  m2 row(a=1, b=2, c=3, d=4, param1='a', param2='b') 

but when add them, overloaded __add__ never gets called , seem regular tuple object out

w = e2 + m2 print(w) (1, 2, 3, 4, 1, 2, 3, 4, 'a', 'b') type(w) tuple 

my __add__ method doesn't seem active on instance objects.

row.__add__? signature: row.__add__(self, other) docstring: new add file:      <ipython-input-535-817d9f528ae7> type:      instancemethod  e.__add__? type:        wrapper_descriptor string form: <slot wrapper '__add__' of 'tuple' objects> docstring:   x.__add__(y) <==> x+y  e2.__add__? type:        method-wrapper string form: <method-wrapper '__add__' of row object @ 0x122614050> docstring:   x.__add__(y) <==> x+y 

what doing wrong? tried subclassing namedtuple('row', ...), indicated in docs https://docs.python.org/2/library/collections.html#collections.namedtuple, couldn't work. couldn't dynamically change named parameters.

here failure

baserow = namedtuple('baserow', 'a, b, c, d')  class row(baserow):     __slots__ = ()      def __new__(cls, *args, **kwargs):         new_fields = set(kwargs.keys()) - set(cls._fields)         cls._fields += tuple(new_fields)         obj = super(row, cls).__new__(cls, *args, **kwargs)         return obj  e = row(a=1, b=2, c=3, d=4, param1='a') typeerror: __new__() got unexpected keyword argument 'param1' 

the __add__ method defined method accessible instances of class type row.

when overrode __new__ method of row class, return object of type namedtuple(...), not row. therefore, further manipulation of objects not have access __add__ method because not rows, namedtuple()s.

as @user2357112 mentioned, seems you're making things difficult , may better off using dictionaries. if need immutable, hashable type each of rows can create sets , use them dictionary keys, convert dictionaries named tuples right before using them way.


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 -