import itertools
from operator import attrgetter
def structure(name, fields):
attributes = {}
for field in fields:
attributes[field] = property(attrgetter('_' + field))
def __init__(self, *args, **kwargs):
for field, value in itertools.chain(zip(fields, args), kwargs.items()):
setattr(self, '_' + field, value)
attributes['__init__'] = __init__
def __repr__(self):
arguments = (field + '=' + repr(getattr(self, field)) for field in fields)
return type(self).__name__ + '(' + ', '.join(arguments) + ')'
attributes['__repr__'] = __repr__
def replace(self, **kwargs):
arguments = {field: getattr(self, field) for field in fields}
arguments.update(kwargs)
return type(self)(**arguments)
attributes['replace'] = replace
return type(name, (object,), attributes)
User = structure('User', ['first_name', 'last_name'])
print(User('Henk', ('de', 'Vries')))
print(User('Henk', last_name=('de', 'Vries')))
print(User('Henk', ('de', 'Vries')).replace(first_name='Sjaak'))
User('Henk', ('de', 'Vries')).first_name = 'error'
aW1wb3J0IGl0ZXJ0b29scwpmcm9tIG9wZXJhdG9yIGltcG9ydCBhdHRyZ2V0dGVyCgoKZGVmIHN0cnVjdHVyZShuYW1lLCBmaWVsZHMpOgoJYXR0cmlidXRlcyA9IHt9CgoJZm9yIGZpZWxkIGluIGZpZWxkczoKCQlhdHRyaWJ1dGVzW2ZpZWxkXSA9IHByb3BlcnR5KGF0dHJnZXR0ZXIoJ18nICsgZmllbGQpKQoKCWRlZiBfX2luaXRfXyhzZWxmLCAqYXJncywgKiprd2FyZ3MpOgoJCWZvciBmaWVsZCwgdmFsdWUgaW4gaXRlcnRvb2xzLmNoYWluKHppcChmaWVsZHMsIGFyZ3MpLCBrd2FyZ3MuaXRlbXMoKSk6CgkJCXNldGF0dHIoc2VsZiwgJ18nICsgZmllbGQsIHZhbHVlKQoJYXR0cmlidXRlc1snX19pbml0X18nXSA9IF9faW5pdF9fCgoJZGVmIF9fcmVwcl9fKHNlbGYpOgoJCWFyZ3VtZW50cyA9IChmaWVsZCArICc9JyArIHJlcHIoZ2V0YXR0cihzZWxmLCBmaWVsZCkpIGZvciBmaWVsZCBpbiBmaWVsZHMpCgkJcmV0dXJuIHR5cGUoc2VsZikuX19uYW1lX18gKyAnKCcgKyAnLCAnLmpvaW4oYXJndW1lbnRzKSArICcpJwoJYXR0cmlidXRlc1snX19yZXByX18nXSA9IF9fcmVwcl9fCgoJZGVmIHJlcGxhY2Uoc2VsZiwgKiprd2FyZ3MpOgoJCWFyZ3VtZW50cyA9IHtmaWVsZDogZ2V0YXR0cihzZWxmLCBmaWVsZCkgZm9yIGZpZWxkIGluIGZpZWxkc30KCQlhcmd1bWVudHMudXBkYXRlKGt3YXJncykKCQlyZXR1cm4gdHlwZShzZWxmKSgqKmFyZ3VtZW50cykKCWF0dHJpYnV0ZXNbJ3JlcGxhY2UnXSA9IHJlcGxhY2UKCglyZXR1cm4gdHlwZShuYW1lLCAob2JqZWN0LCksIGF0dHJpYnV0ZXMpCgoKVXNlciA9IHN0cnVjdHVyZSgnVXNlcicsIFsnZmlyc3RfbmFtZScsICdsYXN0X25hbWUnXSkKCnByaW50KFVzZXIoJ0hlbmsnLCAoJ2RlJywgJ1ZyaWVzJykpKQpwcmludChVc2VyKCdIZW5rJywgbGFzdF9uYW1lPSgnZGUnLCAnVnJpZXMnKSkpCnByaW50KFVzZXIoJ0hlbmsnLCAoJ2RlJywgJ1ZyaWVzJykpLnJlcGxhY2UoZmlyc3RfbmFtZT0nU2phYWsnKSkKClVzZXIoJ0hlbmsnLCAoJ2RlJywgJ1ZyaWVzJykpLmZpcnN0X25hbWUgPSAnZXJyb3InCg==
User(first_name='Henk', last_name=('de', 'Vries'))
User(first_name='Henk', last_name=('de', 'Vries'))
User(first_name='Sjaak', last_name=('de', 'Vries'))
Traceback (most recent call last):
File "./prog.py", line 36, in <module>
AttributeError: can't set attribute