Уведомления

Группа в Telegram: @pythonsu

#1 Март 23, 2014 17:35:30

Dariloff
Зарегистрирован: 2013-11-28
Сообщения: 8
Репутация: +  0  -
Профиль   Отправить e-mail  

регистрация изменений свойств множества экземпляров классов.

Идея простая. Сдаются классы по сценарию одного металасса. У каждого экземпляра есть с рождения флажок changed = False.
В каждый этот класс при создании запихивается вловарь данных, что вревращает объект в отражение полученного словаря dic.
def __init__(self, dic):
self.__dict__=dic

В определённые моменты мне надо знать, были ли изменения в хотя бы 1 аттрибуте или нет.
Видел шикарный видеопример как можно повесить счётчик на каждый метод https://www.youtube.com/watch?v=tZnBtoJoD-o
Т.к. данных в самом классе нет, я в __new__ добавляю только changed = False, остальное ожидаю увидеть в __call__. И вижу. Но одно дело сделать декоратор для метода, а другое - свойство со спрятанной функцией. Что-то вроде дескриптора. Здесь я повис. Если я сначала создаю обычное свойство и после него пытаюсь приравнять ему значение, он стирает всё свойство и добавляет значение.
Делаю например так
def __call__(self, *args, **kwargs):
obj= type.__call__(self, *args, **kwargs)
def _getter(self):
return self.Login

def _setter(self, val):
self.changed=True
self.Login = val

def _deleter(self):
del self.Login
for item, value in obj.__dict__.items():
obj.__dict__.update({item : property(_getter, _setter, _deleter)})
здесь свойство
obj.__dict__=value
здесь свойства уже нет

естественно сами функции дейсриптора нерабочие. Речь пока не о них

Может есть какой универсальный способ реакции на изменение объекта? В джанго всё просто, берёшь и ловишь сигнал.
Я честно признают, что у меня полная каша в голове от getattr, __get__, __getattr__, __getattribute__. Это какой-то ужас, не могу разобраться когда что вызывается.

Отредактировано Dariloff (Март 23, 2014 18:20:09)

Офлайн

#2 Март 23, 2014 19:52:23

sergeek
Зарегистрирован: 2012-06-26
Сообщения: 470
Репутация: +  43  -
Профиль   Отправить e-mail  

регистрация изменений свойств множества экземпляров классов.

class Cls:
    def __init__(self, dic):
        self.__dict__ = dic
        watched = set(dic.keys())
        self.changed = False
 
        def __setattr__(self, slot, value):
            if slot in watched:
                self.changed = True
            super().__setattr__(slot, value)
                 
        Cls.__setattr__ = __setattr__

Офлайн

#3 Март 23, 2014 20:21:38

Dariloff
Зарегистрирован: 2013-11-28
Сообщения: 8
Репутация: +  0  -
Профиль   Отправить e-mail  

регистрация изменений свойств множества экземпляров классов.

Работает для класса. В метаклассе __init__ не видит переданный ему словарь. Классов таких 4. Хочется одним метаклассом описать их поведение. В любом случае спасибо большое!

Офлайн

#4 Март 23, 2014 20:32:47

Dariloff
Зарегистрирован: 2013-11-28
Сообщения: 8
Репутация: +  0  -
Профиль   Отправить e-mail  

регистрация изменений свойств множества экземпляров классов.

Всё! Сделал через __call__ метакласса.
Ещё раз спасибо! Продолжаю достигать дзена.

Результат

class Meta ( type ):
    def __call__(self, load=None, *args, **kwargs):
        obj = type.__call__(self, *args, **kwargs)
        if 'ready' in kwargs:
            obj.__dict__.update(kwargs['ready'])
            watched = set(kwargs['ready'].keys())
            obj.changed = False
             def __setattr__(obj, slot, value):
                if slot in watched:
                    obj.changed = True
                super(obj.__class__, obj).__setattr__(slot, value)
            obj.__class__.__setattr__ = __setattr__
        return obj
Ходил вокруг, да около весь день.

Отредактировано Dariloff (Март 23, 2014 22:03:14)

Офлайн

#5 Март 23, 2014 21:10:43

sergeek
Зарегистрирован: 2012-06-26
Сообщения: 470
Репутация: +  43  -
Профиль   Отправить e-mail  

регистрация изменений свойств множества экземпляров классов.

для количества экземпляров > 1 правильно работает? А то я ошибся там

Офлайн

#6 Март 23, 2014 22:02:44

Dariloff
Зарегистрирован: 2013-11-28
Сообщения: 8
Репутация: +  0  -
Профиль   Отправить e-mail  

регистрация изменений свойств множества экземпляров классов.

Теперь правильно. Ещё раз подправил. Ато до этого работало т.к. забыл в самом классе стереть механизм.

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version