fork(1) download
  1. import itertools
  2. from operator import attrgetter
  3.  
  4.  
  5. def structure(name, fields):
  6. attributes = {}
  7.  
  8. for field in fields:
  9. attributes[field] = property(attrgetter('_' + field))
  10.  
  11. def __init__(self, *args, **kwargs):
  12. for field, value in itertools.chain(zip(fields, args), kwargs.items()):
  13. setattr(self, '_' + field, value)
  14. attributes['__init__'] = __init__
  15.  
  16. def __repr__(self):
  17. arguments = (field + '=' + repr(getattr(self, field)) for field in fields)
  18. return type(self).__name__ + '(' + ', '.join(arguments) + ')'
  19. attributes['__repr__'] = __repr__
  20.  
  21. def replace(self, **kwargs):
  22. arguments = {field: getattr(self, field) for field in fields}
  23. arguments.update(kwargs)
  24. return type(self)(**arguments)
  25. attributes['replace'] = replace
  26.  
  27. return type(name, (object,), attributes)
  28.  
  29.  
  30. User = structure('User', ['first_name', 'last_name'])
  31.  
  32. print(User('Henk', ('de', 'Vries')))
  33. print(User('Henk', last_name=('de', 'Vries')))
  34. print(User('Henk', ('de', 'Vries')).replace(first_name='Sjaak'))
  35.  
  36. User('Henk', ('de', 'Vries')).first_name = 'error'
  37.  
Runtime error #stdin #stdout #stderr 0.11s 10088KB
stdin
Standard input is empty
stdout
User(first_name='Henk', last_name=('de', 'Vries'))
User(first_name='Henk', last_name=('de', 'Vries'))
User(first_name='Sjaak', last_name=('de', 'Vries'))
stderr
Traceback (most recent call last):
  File "./prog.py", line 36, in <module>
AttributeError: can't set attribute