Как правильно удалить файл блокировки в абстрактном классе 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?