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