Skip to content

Instantly share code, notes, and snippets.

@louisswarren
Last active October 9, 2018 12:06
Show Gist options
  • Save louisswarren/aa71963a3e2eeca4db41d6034feab3f8 to your computer and use it in GitHub Desktop.
Save louisswarren/aa71963a3e2eeca4db41d6034feab3f8 to your computer and use it in GitHub Desktop.
Extension of inheriting from namedtuple
def tclass(*argnames, then_do=None):
if len(argnames) == 1 and isinstance(argnames[0], dict):
argnames = argnames[0]
def decorator(cls):
def inner_init(self, *args, **kwargs):
for argname, arg in zip(argnames, args):
self.__setattr__(argname, arg)
for argname in list(argnames)[len(args):]:
self.__setattr__(argname, argnames[argname])
# Doesn't check for multiple values
self.__dict__.update(kwargs)
if then_do:
self.__getattribute__(then_do)()
def inner_repr(self):
reprargs = (repr(self.__getattribute__(argname)) for argname in argnames)
return '{}({})'.format(cls.__name__, ', '.join(reprargs))
cls.__init__ = inner_init
cls.__repr__ = inner_repr
return cls
return decorator
@tclass('x', 'y', then_do='post_init')
class Point:
def post_init(self):
self.length = (self.x ** 2 + self.y ** 2) ** 0.5
print(repr(Point(1, 2)))
print(repr(Point(3, 4)))
print(Point(3, 4).length)
@tclass({'size': 'small', 'empty': True})
class Box:
pass
print(repr(Box()))
print(repr(Box(empty=False)))
print(repr(Box('medium')))
print(repr(Box('large', False)))
"""
Point(1, 2)
Box('small', True)
Box('small', False)
Box('medium', True)
Box('large', False)
"""
from collections import namedtuple
def tclass(argnames):
def decorator(cls):
class inner(namedtuple('inner', argnames), cls):
def __init__(self, *args, **kwargs):
cls.__init__(self, *args, **kwargs)
return inner
return decorator
@tclass('x y')
class Point:
def __init__(self, x, y):
self.length = (self.x ** 2 + self.y ** 2) ** 0.5
print(repr(Point(1, 2)))
print(repr(Point(3, 4)))
print(Point(3, 4).length)
from collections import namedtuple
def tclass(argnames, then_do=None):
def decorator(cls):
class inner(namedtuple('inner', argnames), cls):
def __init__(self, *args, **kwargs):
cls.__init__(*args, **kwargs)
if then_do:
self.__getattribute__(then_do)(*args, **kwargs)
return inner
return decorator
@tclass('x y', then_do='post_init')
class Point:
def post_init(self, x, y):
self.length = (x ** 2 + y ** 2) ** 0.5
print(repr(Point(1, 2)))
print(repr(Point(3, 4)))
print(Point(3, 4).length)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment