| t | def slotgen(number): | t | def slotgen(number): |
| letters = 'abcdefghijklmnopqrstuvwxyz' | | letters = 'abcdefghijklmnopqrstuvwxyz' |
| base = len(letters) | | base = len(letters) |
| | | |
| def decorator(cls): | | def decorator(cls): |
| L = 1 | | L = 1 |
| power = base | | power = base |
| while power < number: | | while power < number: |
| L += 1 | | L += 1 |
| power *= base | | power *= base |
| | | |
| def index_to_name(i): | | def index_to_name(i): |
| chars = [] | | chars = [] |
| for _ in range(L): | | for _ in range(L): |
| chars.append(letters[i % base]) | | chars.append(letters[i % base]) |
| i //= base | | i //= base |
| chars.reverse() | | chars.reverse() |
| return ''.join(chars) | | return ''.join(chars) |
| | | |
| def name_to_index(name): | | def name_to_index(name): |
| if len(name) != L: | | if len(name) != L: |
| return None | | return None |
| idx = 0 | | idx = 0 |
| for ch in name: | | for ch in name: |
| pos = ord(ch) - 97 | | pos = ord(ch) - 97 |
| if pos < 0 or pos >= base: | | if pos < 0 or pos >= base: |
| return None | | return None |
| idx = idx * base + pos | | idx = idx * base + pos |
| return idx | | return idx |
| slots = tuple((index_to_name(i) for i in range(number))) | | slots = tuple((index_to_name(i) for i in range(number))) |
| new_dict = {} | | new_dict = {} |
| for name, value in cls.__dict__.items(): | | for name, value in cls.__dict__.items(): |
| if name.startswith('__'): | | if name.startswith('__'): |
| continue | | continue |
| idx = name_to_index(name) | | idx = name_to_index(name) |
| if idx is not None and idx < number: | | if idx is not None and idx < number: |
| continue | | continue |
| new_dict[name] = value | | new_dict[name] = value |
| new_dict['__slots__'] = slots | | new_dict['__slots__'] = slots |
| return type(cls.__name__, cls.__bases__, new_dict) | | return type(cls.__name__, cls.__bases__, new_dict) |
| return decorator | | return decorator |
| '\n@slotgen(29)\nclass C:\n field = 12\n ab = 100500\n\nc = C()\nc | | '\n@slotgen(29)\nclass C:\n field = 12\n ab = 100500\n\nc = C()\nc |
| .ba = 100500\nfor attr in "aa ab field ba".split():\n try:\n p | | .ba = 100500\nfor attr in "aa ab field ba".split():\n try:\n p |
| rint(f"{attr}={getattr(c, attr)}")\n except AttributeError:\n | | rint(f"{attr}={getattr(c, attr)}")\n except AttributeError:\n |
| print(f"No {attr}")\n' | | print(f"No {attr}")\n' |