Вот сдесь есть две идеи как создавать классы с автоматическими слотами: http://code.activestate.com/recipes/435880/
В первой есть костыль в виде вызова специальной функции в __init__, а вторая работает ещё кривее: сначала берётся исходник всего класса, потом строится синтаксическое дерево(abstract syntax trees, ast) и уже оно обходится и находятся все присвоения к self.
Как превратить __code__ во что-то что можно распарсить я не придумал. Взять __code.co_varnames тоже не получится т.к. в итоге из self.field = 666 туда попадёт только self(что логично). Модуль disasm мне тоже не понравился.
Пока самое элегантное что придумал это получить исходник функции и регекспом его, регекспом! Работает отлично, даже конструкции вида self.x=1;self.y=1; проглотит.
Может у кого ещё есть идеи как это можно реализовать?
class AutoSlots(type):
def __new__(self, cls_name, bases, namespace):
if bases:
#slots can be used with subclassing. For this two problem should be solved:
# exclude slot variables appeared in base classes
# check if all parrents doesn't have __dict__ or slots will be useless
raise Exception("Do not use slots with in nested classes")
#__slots__ may be tuple or other iterable, so we converting it to list
slots = list(namespace.get('__slots__', []))
if '__init__' in namespace:
init = namespace['__init__']
init_source = inspect.getsourcelines(init.__code__)[0]
for line in init_source:
slots += re.findall(r"\s*self\.(\w+)\s*=\s*\w*;?",line)
namespace['__slots__'] = slots
return type.__new__(self, cls_name, bases, namespace)