Как известно, метод python __del__
не должен использоваться для очистки важных вещей, так как не гарантируется, что этот метод вызывается. Альтернативой является использование диспетчера контекста, как описано в нескольких потоках.Как использовать диспетчер контекста, чтобы избежать использования __del__ в python?
Но я не совсем понимаю, как переписать класс для использования диспетчера контекстов. Чтобы разработать, у меня есть простой (нерабочий) пример, в котором класс-оболочка открывает и закрывает устройство, и который должен закрыть устройство, в любом случае экземпляр класса выходит из своей области (исключение и т. Д.).
Первый файл mydevice.py
представляет собой стандартный класс обертку, чтобы открыть и закрыть устройство:
class MyWrapper(object):
def __init__(self, device):
self.device = device
def open(self):
self.device.open()
def close(self):
self.device.close()
def __del__(self):
self.close()
этот класс используется другим классом myclass.py
:
import mydevice
class MyClass(object):
def __init__(self, device):
# calls open in mydevice
self.mydevice = mydevice.MyWrapper(device)
self.mydevice.open()
def processing(self, value):
if not value:
self.mydevice.close()
else:
something_else()
Мой вопрос: Когда я реализовать контекстный менеджер в mydevice.py
с методами __enter__
и __exit__
, как этот класс может обрабатываться в myclass.py
? Мне нужно сделать что-то вроде
def __init__(self, device):
with mydevice.MyWrapper(device):
???
но как с этим обращаться? Может, я забыл что-то важное? Или я могу использовать диспетчер контекста только внутри функции, а не как переменную внутри области класса?
Тот же комментарий, что и раньше: я не знаю заранее, что происходит с устройством, но он будет открыт и использован в нескольких других методах, классах и т. Д. Является ли это тем, что я должен использовать '__del__' вместо этого? – Alex
Я думаю, что '__del __()' является вашим единственным открытием для этого открытого поведения. Имейте в виду, что '__del __()' только не вызывается, если сборщик мусора находит ссылочный цикл с вашим классом. Вы можете даже обнаружить и разрешить это вручную в своем коде, периодически проверяя ['gc.garbage'] (http://docs.python.org/2/library/gc.html#gc.garbage) и нарушая эталонные циклы, которые вызывают проблему. – Cartroo