Python attributeError на del


У меня есть объект класса python, и я хочу присвоить значение одной переменной класса

class Groupclass(Workerclass):
    """worker class"""
    count = 0

    def __init__(self):
        """initialize time"""
        Groupclass.count += 1
        self.membercount = 0;
        self.members = []

    def __del__(self):
        """delte a worker data"""
        Groupclass.count -= 1


if __name__ == "__main__":
    group1 = Groupclass()

Этот результат выполнения верен, но есть сообщение об ошибке, которое говорит:

Exception AttributeError: "'NoneType' object has no attribute 'count'" in <bound method Groupclass.__del__ of <__main__.Groupclass instance at 0x00BA6710>> ignored
Может ли кто-нибудь сказать мне, что я сделал не так?
1 10

1 ответ:

Ваш метод __del__ предполагает, что класс все еще присутствует к моменту его вызова.

Это предположение неверно. Groupclass уже был очищен при выходе из программы Python и теперь имеет значение None.

Сначала проверьте, существует ли глобальная ссылка на класс:

def __del__(self):
    if Groupclass:
        Groupclass.count -= 1

Или используйте type(), чтобы получить локальную ссылку:

def __del__(self):
    type(self).count -= 1

Но обратите внимание, что это означает, что семантика для count изменяется, если Groupclass подкласс (каждый подкласс получает .count атрибут против только Groupclass, имеющего атрибут .count).

Цитирую из документации по крюку __del__:

Предупреждение : из-за опасных обстоятельств, при которых вызываются методы __del__(), исключения, возникающие во время их выполнения, игнорируются, и вместо них выводится предупреждение sys.stderr. Кроме того, когда __del__() вызывается в ответ на удаление модуля (например, при выполнении программы), другие глобалы, на которые ссылается метод __del__(), могут быть вызваны в ответ на удаление модуля. уже были удалены или в процессе сноса (например, остановка импортного оборудования). По этой причине методы __del__() должны выполнять абсолютный минимум, необходимый для поддержания внешних инвариантов. Начиная с версии 1.5, Python гарантирует, что глобалы, имя которых начинается с одного подчеркивания, удаляются из своего модуля до удаления других глобалов; если других ссылок на такие глобалы не существует, это может помочь гарантировать, что импортированные модули по-прежнему доступны в модуле. время, когда вызывается метод __del__().

Если вы используете Python 3, применяются два дополнительных Примечания:

  • CPython 3.3 автоматически применяетрандомизированную хэш-соль к ключам str, используемым в словаре globals; это также влияет на порядок очистки глобалов, и этоможет быть , что вы видите проблему только нанекоторых запусках.

  • CPython 3.4 больше не устанавливает глобалы в None (в большинстве случаев), как perSafe Object Finalization ; см.PEP 442 .