Можно использовать atexit для этого и регистр, любой очищает задачи, которые будут выполнены, когда программа выходит.
atexit.register (func [*args [** kargs]])
В Вашем процессе очистки, можно также реализовать собственное ожидание и уничтожить его, когда желаемый тайм-аут происходит.
>>> import atexit
>>> import sys
>>> import time
>>>
>>>
>>>
>>> def cleanup():
... timeout_sec = 5
... for p in all_processes: # list of your processes
... p_sec = 0
... for second in range(timeout_sec):
... if p.poll() == None:
... time.sleep(1)
... p_sec += 1
... if p_sec >= timeout_sec:
... p.kill() # supported from python 2.6
... print 'cleaned up!'
...
>>>
>>> atexit.register(cleanup)
>>>
>>> sys.exit()
cleaned up!
Примечание - Зарегистрированные функции не будут выполнены, если этот процесс (родительский процесс) будет уничтожен.
следующий метод окон больше не необходим для Python> = 2.6
, Вот способ уничтожить процесс в окнах. Ваш объект Popen имеет изодромный с предварением атрибут, таким образом, можно просто назвать его [1 114] успех = win_kill (p.pid) (Потребности pywin32 установленный):
def win_kill(pid):
'''kill a process by specified PID in windows'''
import win32api
import win32con
hProc = None
try:
hProc = win32api.OpenProcess(win32con.PROCESS_TERMINATE, 0, pid)
win32api.TerminateProcess(hProc, 0)
except Exception:
return False
finally:
if hProc != None:
hProc.Close()
return True
Вы разрабатываете библиотеку , компонент, который будет использоваться другими приложениями.
Поэтому в ожидаемых случаях, о которых вы упомянули, я бы обязательно использовал исключения, чтобы сообщить вызывающему приложению, что что-то не так. Вы должны определить собственное исключение для каждого из этих сценариев, а затем четко задокументировать, когда они могут произойти.
Это затем позволяет клиентскому коду приложения принять решение о том, как лучше действовать. Только клиентское приложение может принять это решение, и четко задокументированные исключения в значительной степени этому помогают.
Лучшее в настраиваемом исключении - это то, что вы можете предоставить несколько значимых / полезных фрагментов данных, относящихся к проблеме / исключению. Эти данные также красиво инкапсулируются в один объект. Сравните это с кодами ошибок и возвращаемыми значениями.
Производительность может быть проблемой, но только в том случае, если исключение возникает в замкнутом цикле или в другой ситуации с высокой активностью. Чтобы избежать этого, вы также можете применить шаблон, используемый .NET Framework, а именно предоставить методы Try .... () (например, TryParse ()
), которые возвращают логическое значение, указывающее, было ли действие успешным или неудачным.
В любом случае я бы сначала пошел с настраиваемыми исключениями, а затем провел бы тестирование производительности, чтобы действительно увидеть, есть ли определенные части библиотеки, которые могут нуждаться в оптимизации.
С RS232, если у вас не включено аппаратное подтверждение связи (а в большинстве случаев люди этого не делают), вы просто не увидите больше данных, поступающих по линии. У вас нет никакого способа узнать, подключено ли устройство, кроме того факта, что на ПК ничего не отправляется.
Я бы классифицировал 1 и 3 вместе как RS232TimeoutError, а 2, вероятно, как RS232AuthenticationError.
Вообще говоря, TimeoutError указывает, что удаленное устройство заблокировано или просто не подключено. Ошибка аутентификации - это своего рода ProtocolError, но она немного отличается тем, что со связью все в порядке, но удаленное устройство просто сказало «нет» созданию соединения с ПК.
Я думаю, что установка этих исключений вполне оправдана: вы никогда не ожидаете ошибки тайм-аута во время нормальной работы,
Независимо от того, генерируете ли вы исключение или нет, следствие типа функции.
Итак, я думаю, я говорю, что вы должны выдвинуть проблему из «Должен ли я генерировать исключение?» к "
Я бы использовал исключения в следующем подходе (на основе разработки по контракту)
Таким образом, если пользователь API может закодировать свою ключевую логику, используя структуры if-then-else.
Если возникают непредвиденные ситуации (например, из-за тонких проблем с синхронизацией), будет сгенерировано исключение: разработчик может перехватить это исключение и обработать его. Но обратите внимание: это не обязательно должно быть в том месте, где был вызван метод: он может быть выше / раньше в стеке вызовов, в центральном месте, где обрабатываются все странные исключения
Я проделал некоторую работу по автоматическому анализу код обработки ошибок в многомиллионных строках программ на C. Они были основаны на стандартах кодирования, требующих проверки от руки и распространения кодов ошибок. Оказывается, разработчики не любят писать такой код, они его забывают и легко ошибаются. Фактически мы обнаружили 2 отклонения от стандартов кодирования (2 ошибки, Т. Турве. D обнаруживает неисправности в Обработка исключений на основе идиом . В материалах от 28-го Международная конференция по программному обеспечению Инжиниринг (ICSE'06), стр. 242-251, ACM Press, 2006.
Вкратце: (1) я бы использовал логические инспекторы (2) исключения могут быть обнаружены в местах выше в стеке вызовов; (3) полагаться на коды ошибок на практике небезопасно.
Не используйте исключения для обычных или ожидаемые ошибки, или для нормального потока control.
В своих реализациях метода избегайте преднамеренного создания исключения, чтобы изменить поток выполнения, обработать специальную логику, особые случаи или обработать нормальные или ожидаемые ошибки. Например, в следующей функции следует удалить обработку исключений. (Он обрабатывает обычные или ожидаемые ошибки, но, как сказано в примечании, Convert.ToString на самом деле не выйдет из строя.) Существует незначительное снижение производительности из-за времени, необходимого для «настройки» обработки исключений в методе. Это несущественное попадание, но если вы вызываете эту функцию в цикле, это может стать значительным. Если этот метод находится в библиотеке, пусть любые исключения всплывают до пользователя библиотеки. (Пользовательские исключения различаются, см. Ответ Эша.)
Public Function Nz(ByVal value As String, ByVal valueIfNothing As String) As String
Try
Dim sValue As String = System.Convert.ToString(value) 'using Convert.ToString on purpose
If IsNothing(sValue) Then
Return valueIfNothing
Else
Return sValue
End If
Catch ex As Exception
'Convert.ToString handles exceptions, but just in case...
Debug.Fail("Nz() failed. Convert.ToString threw exception.")
Return String.Empty
End Try
End Function
Вот «лучшая» реализация метода: опасения, что исключения могут повлиять производительность отрицательно.
Избегайте проектирования всего как функции, которая возвращает истину / ложь с параметрами «out», просто чтобы избежать «воображаемых» проблем производительности при использовании исключений.
Выбор не должен быть между выдачей исключения или возвратом кода ошибки. Попробуйте вернуть объект исключения в исключительном состоянии. Падение производительности заключается не в создании исключения, а в его выбросе. Затем вызывающий может проверить возвращаемое значение "null". Возвращаемое исключение может быть возвращением функции или одним из нескольких выходных параметров.
Не используйте исключения для обычных или ожидаемые ошибки, или для нормального потока control.
В реализациях вашего метода избегайте преднамеренного создания исключения, чтобы изменить поток выполнения, обработать специальную логику, особые случаи или обработать нормальные или ожидаемые ошибки. Например, в следующей функции следует удалить обработку исключений. (Он обрабатывает обычные или ожидаемые ошибки, но, как сказано в примечании, Convert.ToString на самом деле не выйдет из строя.) Существует незначительное снижение производительности из-за времени, необходимого для «настройки» обработки исключений в методе. Это незначительный удар, но если вы вызываете эту функцию в цикле, это может стать значительным. Если этот метод находится в библиотеке, пусть любые исключения всплывают до пользователя библиотеки. (Пользовательские исключения разные, см. Ответ Эша.)
Public Function Nz(ByVal value As String, ByVal valueIfNothing As String) As String
Try
Dim sValue As String = System.Convert.ToString(value) 'using Convert.ToString on purpose
If IsNothing(sValue) Then
Return valueIfNothing
Else
Return sValue
End If
Catch ex As Exception
'Convert.ToString handles exceptions, but just in case...
Debug.Fail("Nz() failed. Convert.ToString threw exception.")
Return String.Empty
End Try
End Function
Вот «лучшая» реализация метода:
Public Function Nz(ByVal value As String, ByVal valueIfNothing As String) As String
Dim sResult As String = String.Empty
Dim sValue As String = System.Convert.ToString(value) 'using Convert.ToString on purpose
If IsNothing(sValue) Then
sResult = valueIfNothing
Else
sResult = sValue
End If
Return sResult
End Function
Исключения были разработаны именно для этого - исключительных обстоятельств. Я стараюсь думать об этом так: если вы предполагаете, что все, от чего вы зависите, работает нормально большую часть времени, а метод X не работает, тогда это исключительное обстоятельство, потому что обычно этого не происходит, и вы должны определить исключения поймать ситуацию.
Итак, в вашей ситуации вы предполагаете, что устройство работает. Поэтому исключительными обстоятельствами в этом случае являются то, что устройство не принимает соединение, оно отклоняет соединение, оно не принимает данные, которые вы ему отправляете, или вы не получаете данные, которые оно должно отправлять и т. Д. Если ваши устройства обычно выключаются несколько раз в день, тогда вы ожидаете, что они будут отключены, поэтому используйте коды возврата или «bool IsDeviceOn ();» метод, чтобы проверить это перед подключением.
Если что-то, что вы действительно ожидаете , произойдет при нормальных обстоятельствах, например, запросите у устройства его возможности, но то, что вам нужно, недоступно, тогда используйте коды возврата или метод типа bool - например "bool DoesDeviceHaveThisCapability ();" Не ловите исключение, если это не так.
Другой пример (для приложений с графическим интерфейсом) - ввод данных пользователем. Не используйте для этого исключения, потому что вы ожидаете, что пользователь введет что-то неправильно - мы не идеальны.
У меня возникли серьезные проблемы с производительностью из-за использования исключений, когда они не были действительно исключительными обстоятельствами. Один из примеров был, когда я обрабатывал файл данных размером 2 ГБ 2-3 раза в день. В некоторых строках были действующие цены в формате 0.00. Некоторые этого не сделали. Я использовал FormatException, чтобы поймать те, которые этого не сделали.
Два года спустя, когда мне представился шанс получить на нем анализатор производительности, эта конкретная строка, которая перехватила исключение, отвечала за 80% времени, использованного для анализа файла. Я изменил это, чтобы вместо int использовать метод TryParse (), и получил значительное увеличение скорости.
Для ваших примеров я, вероятно, использовал бы: