2016-11-24 3 views
0

Я пытаюсь обернуть плохо написанный модуль Python (который я не контролирую) в классе. Проблема в том, что если я не буду явным образом вызывать функцию закрытия этого модуля, тогда процесс python зависает при выходе, поэтому я попытался обернуть модуль классом, который имеет метод del, однако метод del делает кажется, не вызваны исключениями.Python __del__ не вызвал исключение

Пример:

class Test(object): 
    def __init__(self): 
     # Initialize the problematic module here 
     print "Initializing" 

    def __del__(self): 
     # Close the problematic module here 
     print "Closing" 

t = Test() 
# This raises an exception 
moo() 

В этом случае дель не вызывается и Python зависает. Мне нужно как-то заставить Python вызывать del сразу же, когда объект выходит из области видимости (например, C++). Обратите внимание, что я не контролирую проблемный модуль (т. Е. Не могу исправить ошибку, которая вызывает это в первую очередь), а также не контролирует того, кто использует класс оболочки (не может заставить их использовать «с», поэтому я могу 't использовать выход либо).

Есть ли достойный способ решить эту проблему?

Спасибо!

+0

Не используйте __del__. Это не C++ или язык, созданный для деструкторов. Метод __del__ действительно должен быть удален в Python 3.x, хотя я уверен, что кто-то найдет вариант использования, который имеет смысл. Если вам нужно использовать __del__, имейте в виду основные ограничения на каждый http://docs.python.org/reference/datamodel.html – harshil9968

+1

Оберните его менеджером контекста? – jonrsharpe

+0

Как я уже сказал, у меня нет контроля над тем, кто использует класс. Я не могу заставить их использовать «с». – Dan

ответ

1

Если вы хотите, чтобы какой-то ресурс был выпущен на исключение, подумайте о парадигме __enter__ + __exit__.

class Test(object): 
    def __enter__(self): 
     pass 

    def __exit__(self): 
     pass # Release your resources here 

with Test() as t: 
    moo() 

Когда выполнение переходит в «с» блока, метод __enter __() «т» называется, а затем он покидает блок из-либо нормального потока, или исключение, метод __exit __ () 't'.

+0

Обратите внимание на мою последнюю часть комментария - я не могу контролировать, кто использует класс оболочки или как он будет использоваться, т. Е. Я не могу заставить их использовать «с». Любое решение должно быть реализовано только внутри кода класса-оболочки. – Dan

+0

Хорошо, но у вас есть контроль над кодом, который использует класс? Вы можете использовать \ _ \ _ enter \ _ \ _/\ _ \ _ exit \ _ \ _ в этом клиентском коде. Я положил класс Test, чтобы проиллюстрировать эту идею. Существуют также другие способы реализации операций ввода/вывода, например. используя @ contextlib.contextmanger. –

+0

Привет, у меня нет никакого контроля над кодом, который использует класс. – Dan

Смежные вопросы