Inspired by this answer to a different question, here is my proposed solution based on a metaclass and using super
(to handle future subcalssing correctly). It is quite similar to justinfay's answer.
from collections import namedtuple
NodeTuple = namedtuple("NodeTuple", ("val", "left", "right"))
class NodeMeta(type):
def __call__(cls, val, left=None, right=None):
return super(NodeMeta, cls).__call__(val, left, right)
class Node(NodeTuple, metaclass=NodeMeta):
__slots__ = ()
Then:
>>> Node(1, Node(2, Node(4)),(Node(3, None, Node(5))))
Node(val=1, left=Node(val=2, left=Node(val=4, left=None, right=None), right=None), right=Node(val=3, left=None, right=Node(val=5, left=None, right=None)))