При тестировании приложения, созданного с использованием API остальных, я обнаружил такое поведение, которого я не понимаю.
Давайте начнем с воспроизведения похожей ошибки следующим образом -
В файле call.py
-
Обратите внимание , что в этом файле есть код, который проявляется визуально, например GUI, который работает вечно. Здесь я просто показываю вам представление и намеренно заставляю его поднять исключение, чтобы показать вам проблему. Сделав запрос get и затем попытавшись разобрать результат, так как json вызовет JSONDecodeError
.
import requests
from time import sleep
sleep(3)
uri = 'https://google.com'
r = requests.get(uri)
response_dict = r.json()
Поскольку я хочу запустить его как процесс-демон, я отделил этот процесс от терминала, который запустил его, используя следующую уловку -
В файле start.py
-
import subprocess
import sys
subprocess.Popen(["python3", "call.py"])
sys.exit(0)
А потом я выполняю python3 start.py
Это очевидно разъединяет процесс, потому что если нет исключений, визуальное проявление работает отлично.
Однако в случае исключения я немедленно вижу этот вывод в терминале, хотя я получил новое приглашение после вызова python3 start.py
-
$ python3 start.py
$ Traceback (most recent call last):
File "call.py", line 7, in <module>
response_dict = r.json()
File "/home/walker/.local/lib/python3.6/site-packages/requests/models.py", line 896, in json
return complexjson.loads(self.text, **kwargs)
File "/usr/lib/python3/dist-packages/simplejson/__init__.py", line 518, in loads
return _default_decoder.decode(s)
File "/usr/lib/python3/dist-packages/simplejson/decoder.py", line 370, in decode
obj, end = self.raw_decode(s)
File "/usr/lib/python3/dist-packages/simplejson/decoder.py", line 400, in raw_decode
return self.scan_once(s, idx=_w(s, idx).end())
simplejson.errors.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
Теперь я понимаю, что все исключения ДОЛЖНЫ обрабатываться в самой программе. И я сделал это после этой странной проблемы, но что мне не понятно, это , почему это вообще произошло вообще ?
Этого не произойдет, если я выйду из терминала и перезапущу терминал (визуальное проявление застревает в случае трассировки, и не выводится ни на один терминал, как ожидалось)
Почему разъединенный процесс ведет себя так?
ПРИМЕЧАНИЕ : для меня обязательна развязка. Крайне важно, чтобы графический интерфейс выполнялся как фоновый или демонический процесс, а терминал, который его порождает, освобождается от него.