Может ли класс владеть контент-менеджером на python?

#python-3.x #contextmanager

Вопрос:

У меня есть класс, который управляет некоторыми общими ресурсами и в настоящее время предоставляет метод get_X() и put_X() для доступа к ресурсам. Лучшим интерфейсом для этого было бы использование контекстного менеджера для каждого ресурса, как в

 with ResourceManager.X() as x:  # do stuff  

Но я использую класс виджета QT5, который захватывает ресурс, затем он настраивается и должен освободить ресурс, когда виджет будет уничтожен:

 class MyWidget(QtGui.Widgets.QTableWidget):  def conf(self):  self.x = ResourceManager.get_x()   def closeEvent(self, event):  ResourceManager.put_x()  super().closeEvent()  

Итак, существует ли более питонический способ, аналогичный конструкции контекстного менеджера «с», для сохранения ресурса, выделенного для времени выполнения класса?

Примечание: Qt5 не допускает множественного наследования

Обновить:

Загрузчик файлов пользовательского интерфейса Qt5 не позволяет передавать аргументы __init__ , поэтому я добавил conf() метод настройки пользовательских виджетов после загрузки файлов пользовательского интерфейса. Вот почему ResourceManager.get_x() этого нет __init__ .

Что я хотел бы сделать, так это избавиться от put_x() звонка. Я хочу, чтобы ресурс автоматически освобождался python при удалении класса. Есть много виджетов и ресурсов, и их легко put_x() где-то забыть, поэтому я не хочу вручную балансировать вызовы get/put.

Другая проблема связана с исключениями, когда используется несколько ресурсов. Если исключение произойдет, скажем, после 3-го ресурса, то должны быть освобождены только эти 3. Еще одна вещь, которую я не хочу отслеживать вручную.

Ответ №1:

Никогда раньше не использовал QT, но первое, что приходит мне на ум __init__ , __del__ — это методы и, вызываемые соответственно при создании и уничтожении экземпляра класса.

Вы могли бы попробовать следующее:

 class MyWidget(QtGui.Widgets.QTableWidget):  def __init__(self):  super().__init__()  self.x = ResourceManager.get_x()   def __del__(self):  ResourceManager.put_x()  super().__del__()  

Моя единственная проблема заключается в том, что QT фактически удаляет класс, если он больше не используется. Попробуйте и дайте мне знать

 super().closeEvent()  

Комментарии:

1. Это в основном то, что я уже использую. Я хочу избавиться от put_x() вызова и вызвать python GC, когда класс фактически удален.