Как определить, что код Python выполняется через отладчик?

Есть ли простой способ определить в коде Python, что этот код выполняется через отладчик Python?

У меня есть небольшое приложение Python, которое использует код Java (спасибо JPype). Когда я отлаживаю часть Python, я бы хотел, чтобы встроенная JVM также имела параметры отладки.

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
32
0
8 161
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

Беглый взгляд на документацию pdb и исходный код не похоже, что есть встроенный способ сделать это. Я предлагаю вам установить переменную среды, которая указывает на то, что выполняется отладка, и чтобы ваше приложение ответило на это.

$ USING_PDB=1 pdb yourprog.py

Затем в yourprog.py:

import os
if os.environ.get('USING_PDB'):
    # debugging actions
    pass

Отладчики Python (а также профилировщики и инструменты покрытия) используют функцию sys.settrace (в модуле sys) для регистрации обратного вызова, который вызывается при возникновении интересных событий.

Если вы используете Python 2.6, вы можете вызвать sys.gettrace(), чтобы получить текущую функцию обратного вызова трассировки. Если это не None, то вы можете предположить, что вам следует передавать параметры отладки в JVM.

Непонятно, как это можно было сделать до версии 2.6.

Хотя это кажется более чистым способом, он не работает в pdb, если не установлена ​​точка останова.

OOO 05.12.2014 10:37

Хм, вы правы - это должна быть оптимизация, которую использует отладчик. Тем не менее, большую часть времени, когда вы работаете в отладчике, у вас будет установлена ​​точка останова.

babbageclunk 05.12.2014 14:21

@babbageclunk, а не если вы просто пытаетесь посмотреть на окружающую среду, когда программа вылетает (мой самый распространенный способ делать что-то: python -m pdb <program>).

Casey Kuball 14.06.2019 01:50

Вы можете проверить наличие альтернативных пользователей трассировки, таких как pytest-cov ... если это действительно отладчик, он должен быть типа с pydevd в имени.

Chris R. Donnelly 30.01.2021 02:44

Вы можете попытаться заглянуть в свою трассировку стека.

https://docs.python.org/library/inspect.html#the-interpreter-stack

когда вы попробуете это в сеансе отладчика:

import inspect
inspect.getouterframes(inspect.currentframe()

вы получите список записей кадров и сможете просмотреть любые кадры, которые относятся к файлу pdb.

Ответ принят как подходящий

Решение, работающее с Python 2.4 (должно работать с любой версией выше 2.1) и Pydev:

import inspect

def isdebugging():
  for frame in inspect.stack():
    if frame[1].endswith("pydevd.py"):
      return True
  return False

То же самое должно работать с pdb, просто заменив pydevd.py на pdb.py. Как и предполагал do3cc, он пытается найти отладчик в стеке вызывающего.

Полезные ссылки:

Один вкладыш: any(True for frame in inspect.stack() if frame[1].endswith('pydevd.py'))

Mattwmaster58 10.04.2020 20:59

Если вы используете Pydev, вы можете обнаружить это следующим образом:

import sys
if 'pydevd' in sys.modules: 
    print "Debugger"
else:
    print "commandline"

Аналогично if 'pdb' in sys.modules: ... при использовании pdb.

Jason R. Coombs 13.01.2019 19:01

Я обнаружил, что этот метод неприменим при некоторых обстоятельствах, таких как когда тесты запускаются с pytest.

Jason R. Coombs 13.01.2019 20:52

Другой способ сделать это зависит от того, как запускается ваш интерпретатор Python. Это требует, чтобы вы запускали Python с использованием -O для производства и без -O для отладки. Так что это требует внешней дисциплины, которую трудно поддерживать ... но, опять же, это может идеально соответствовать вашим процессам.

Из документации python (см. «Встроенные константы» здесь или здесь):

__debug__
This constant is true if Python was not started with an -O option.

Использование будет примерно таким:

if __debug__:
    print 'Python started without optimization'

Это не совсем ответ на вопрос - вы получаете __debug__, даже когда нет работает под отладчиком (но не использовал флаг «оптимизировать» -O).

dsz 26.12.2020 14:49

В самом деле, отсюда следует предостережение «требуется внешняя дисциплина».

Travelling Man 27.12.2020 18:33

Я нашел более чистый способ сделать это,

Просто добавьте следующую строку в свой manage.py

#!/usr/bin/env python
import os
import sys

if __debug__:
    sys.path.append('/path/to/views.py')


if __name__ == "__main__":
    ....

Затем он автоматически добавит его при отладке.

Нет. Это просто зависит от того, запускали ли вы python с флагом -o.

Christopher Barber 11.03.2020 17:37

Другой альтернативой, если вы используете Pydev, который также работает в многопоточности, является:

try:
    import pydevd
    DEBUGGING = True
except ImportError:
    DEBUGGING = False

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