class Structure: _fields = () def __init__(self, *args): if len(args) != len(self._fields): raise TypeError(f'Expected {len(self._fields)} arguments') for pos, field in enumerate(self._fields): setattr(self, field, args[pos]) def __repr__(self): args = map(lambda field: f"{field}={getattr(self, field)!r}", self._fields) return f"{type(self).__name__}({', '.join(args)})" def __setattr__(self, name, value): if name in self._fields or name[0] == '_': super().__setattr__(name, value) else: raise AttributeError(f"No attribute {name}")