| f | def slotgen(number): | f | def slotgen(number): |
| | | |
| def decorator(cls): | | def decorator(cls): |
| import string | | import string |
| import itertools | | import itertools |
| n | chars = string.ascii_lowercase | n | letters = string.ascii_lowercase |
| name_length = 1 | | length = 1 |
| while len(chars) ** name_length < number: | | while len(letters) ** length < number: |
| name_length += 1 | | length += 1 |
| slot_list = [] | | slots = [] |
| for name_parts in itertools.product(chars, repeat=name_length): | | for combo in itertools.product(letters, repeat=length): |
| if len(slot_list) >= number: | | if len(slots) >= number: |
| break | | break |
| n | slot_list.append(''.join(name_parts)) | n | slots.append(''.join(combo)) |
| base_attrs = {attr_name: attr_value for attr_name, attr_value in | | original_attrs = {name: value for name, value in cls.__dict__.it |
| cls.__dict__.items() if not attr_name.startswith('__')} | | ems() if not name.startswith('__')} |
| new_class_dict = {'__slots__': slot_list} | | class_namespace = {'__slots__': slots} |
| for attr_name, attr_value in base_attrs.items(): | | for name, value in original_attrs.items(): |
| if attr_name not in slot_list: | | if name not in slots: |
| new_class_dict[attr_name] = attr_value | | class_namespace[name] = value |
| | | |
| n | def custom_setattr(self, name, value): | n | def __setattr__(self, name, value): |
| if name in base_attrs and name not in self.__slots__: | | if name in original_attrs and name not in self.__slots__: |
| raise AttributeError(f"Can't set attribute '{name}'") | | raise AttributeError(f"Can't set attribute '{name}'") |
| object.__setattr__(self, name, value) | | object.__setattr__(self, name, value) |
| t | new_class_dict['__setattr__'] = custom_setattr | t | class_namespace['__setattr__'] = __setattr__ |
| return type(cls.__name__, cls.__bases__, new_class_dict) | | return type(cls.__name__, cls.__bases__, class_namespace) |
| return decorator | | return decorator |