Как правильно удалить файл блокировки в абстрактном классе Python?

У меня есть скрипт Python3 Cron, который состоит из MyCron класс и MyIMAP учебный класс.

MyCron class является абстрактным классом, который обеспечивает запуск только одного экземпляра скрипта. Он создает и уничтожает файл блокировки и выбрасывает SingleInstanceExeption когда cron пытается запустить скрипт, когда он уже запущен.

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

В обоих классах я переигрываю __del__ метод. В MyCron потому что мне нужно снять замок, и в MyIMAP закрыть соединение.

Я получаю странные результаты (объекты больше не существуют), когда __del__ вызывается. Вот пример кода:

class MyCron(object):
    def __init__(self, jobname=os.path.basename(sys.argv[0]).split('.')[0]):
        self.logger = logging.getLogger(__name__)
        self.initialized = False
        lockfilename  = "mycron"
        lockfilename += "-%s.lock" % jobname if jobname else ".lock"
        self.lockfile = os.path.normpath(tempfile.gettempdir() + '/' + lockfilename)
        self.logger.debug("MyCron lockfile: " + self.lockfile)
        self.fp = open(self.lockfile, 'w')
        self.fp.flush()
        try:
            fcntl.lockf(self.fp, fcntl.LOCK_EX | fcntl.LOCK_NB)
            self.initialized = True
        except IOError:
            self.logger.warning("Another %s MyCron is already running, quitting." % jobname)
            raise SingleInstanceException()
            self.initialized = False

    def __del__(self):
        if not self.initialized:
            return
        try:
            fcntl.lockf(self.fp, fcntl.LOCK_UN)
            # os.close(self.fp)
            if os.path.isfile(self.lockfile):
                os.unlink(self.lockfile)
        except Exception as e:
            if self.logger:
                self.logger.warning(e)
            else:
                print("Unloggable error: %s" % e)
            sys.exit(-1)

class MyIMAP(MyCron):
    def __init__(self, server, username, password, port=993, timeout=60):
        super(MyIMAP, self).__init__()
        self.server     = server
        self.username   = username
        self.password   = password
        self.port       = port
        self.connection = None
        if self.initialized:
            socket.setdefaulttimeout(timeout)
            self.connect()
            self.login()

    def __del__(self):
        super(MyIMAP, self).__del__()
        if self.initialized and self.connection:
            self.connection.logout()
            self.logger.info("Close connection to %s:%d" % (self.server, self.port))

    ...

Я понимаю, что это связано с непредсказуемым характером __del__ метод, и я, вероятно, должен реализовать это по-другому. Какова лучшая практика здесь для Python 3?

0 ответов

Другие вопросы по тегам