Python attributeError on __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 ответ
Ваш __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
(в большинстве случаев), согласно завершению Safe Object; см. PEP 442.
Когда __del__()
вызванный метод, Groupclass может быть восстановлен с помощью механизма сборки мусора, поэтому использование Groupclass.xxx может завершиться ошибкой. Но вы можете получить доступ к переменной count черезself.__class__.count
. Код нравится ниже:
def __del__(self):
self.__class__.count -= 1