При печати трассировки интерпретатор теперь будет указывать точное выражение, вызвавшее ошибку, а не только строку.
Например:
Traceback (most recent call last): File "distance.py", line 11, in <module> print(manhattan_distance(p1, p2)) ^^^^^^^^^^^^^^^^^^^^^^^^^^ File "distance.py", line 6, in manhattan_distance return abs(point_1.x - point_2.x) + abs(point_1.y - point_2.y) ^^^^^^^^^ AttributeError: 'NoneType' object has no attribute 'x'
Предыдущие версии интерпретатора, при возникновении ошибки указывали только строку, что делало неясным, какой объект был None
. Эти расширенные ошибки также могут быть полезны при работе с глубоко вложенными объектами словарей dict
и вызовами нескольких функций:
Traceback (most recent call last): File "query.py", line 37, in <module> magic_arithmetic('foo') File "query.py", line 18, in magic_arithmetic return add_counts(x) / 25 ^^^^^^^^^^^^^ File "query.py", line 24, in add_counts return 25 + query_user(user1) + query_user(user2) ^^^^^^^^^^^^^^^^^ File "query.py", line 32, in query_user return 1 + query_count(db, response['a']['b']['c']['user'], retry=True) ~~~~~~~~~~~~~~~~~~^^^^^ TypeError: 'NoneType' object is not subscriptable
А также сложные арифметические выражения:
Traceback (most recent call last): File "calculation.py", line 54, in <module> result = (x / y / z) * (a / b / c) ~~~~~~^~~ ZeroDivisionError: division by zero
Кроме того, информация, используемая функцией расширенной трассировки, доступна через общий API, который можно использовать для сопоставления инструкций байт-кода с местоположением исходного кода. Эту информацию можно получить с помощью новой функции Python 3.11:
Codeobject.co_positions()
:Возвращает итерацию по позициям исходного кода каждой инструкции байт-кода в объекте кода Codeobject
.
Итератор возвращает кортежи, содержащие (start_line, end_line, start_column, end_column)
. i-й кортеж соответствует позиции исходного кода, скомпилированного в i-ю инструкцию. Информация столбца представляет собой 0-индексированные смещения байтов utf-8 в данной исходной строке.
Эта позиционная информация может отсутствовать. Неполный список случаев, когда это может произойти:
-X no_debug_ranges
..pyc
, скомпилированного с использованием -X no_debug_ranges
.Когда это происходит, некоторые или все элементы возвращаемого кортежа могут иметь значение None
.
Примечание. Функция
codeobject.co_positions()
требует сохранения позиций столбцов в объектах кода, что может привести к небольшому увеличению использования памяти интерпретатором и использования диска для скомпилированных файлов Python. Чтобы избежать сохранения дополнительной информации и деактивировать печать дополнительной информации о трассировке, необходимо использовать параметр командной строки-X no_debug_ranges
или переменную средыPYTHONNODEBUGRANGES
.
Codeobject - объект кода который представляют собой байт-компилированный исполняемый код Python или байт-код. Разница между объектом кода и объектом функции заключается в том, что объект функции содержит явную ссылку на глобальные переменные функции (модуль, в котором он был определен), в то время как объект кода не содержит контекста; также значения аргументов по умолчанию хранятся в объекте функции, а не в объекте кода (поскольку они представляют собой значения, вычисляемые во время выполнения). В отличие от объектов функций, объекты кода неизменяемы и не содержат ссылок (прямых или косвенных) на изменяемые объекты.