Чтение онлайн

на главную - закладки

Жанры

Язык программирования Python
Шрифт:

stmt

simple_stmt

small_stmt

print_stmt

token.NAME 'print'

test

and_test

not_test

comparison

expr

xor_expr

and_expr

shift_expr

arith_expr

term

factor

power

atom

token.NUMBER '2'

token.STAR '*'

factor

power

atom

token.NUMBER '2'

token.NEWLINE ''

token.ENDMARKER ''

Получение байт–кода

После того как получено дерево синтаксического разбора, компилятор должен

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

Листинг

import parser

prg = ""«print 2*2»""

ast = parser.suite(prg)

code = ast.compile('filename.py')

exec code

prg = ""«2*2»""

ast = parser.expr(prg)

code = ast.compile('filename1.py')

print eval(code)

Функция parser.suite (или parser.expr) возвращает AST–объект (дерево синтаксического анализа), которое методом compile компилируется в Python байт–код и сохраняется в кодовом объекте code. Теперь этот код можно выполнить (или, в случае выражения — вычислить) с помощью оператора exec (или функции eval).

Здесь необходимо заметить, что недавно в Python появился пакет compiler, который объединяет модули для работы анализа исходного кода на Python и генерации кода. В данной лекции он не рассматривается, но те, кто хочет глубже изучить эти процессы, может обратиться к документации по Python.

Изучение байт–кода

Для изучения байт–кода Python–программы можно использовать модуль dis (сокращение от «дизассемблер»), который содержит функции, позволяющие увидеть байт–код в мнемоническом виде. Следующий пример иллюстрирует эту возможность:

Листинг

>>> def f:

… print 2*2

>>> dis.dis(f)

2 0 LOAD_CONST 1 (2)

3 LOAD_CONST 1 (2)

6 BINARY_MULTIPLY

7 PRINT_ITEM

8 PRINT_NEWLINE

9 LOAD_CONST 0 (None)

12 RETURN_VALUE

Определяется функция f, которая должна вычислить и напечатать значение выражения 2*2. Функция dis модуля dis выводит код функции f в виде некого «ассемблера», в котором байт–код Python представлен мнемоническими именами. Следует заметить, что при интерпретации используется стек, поэтому LOAD_CONST кладет значение на вершину стека, а BINARY_MULTIPLY берет со стека два значения и помещает на стек результат их перемножения. Функция без оператора return возвращает значение None. Как и в случае с кодами для микропроцессора, некоторые байт–коды принимают параметры.

Мнемонические имена можно увидеть в списке dis.opname (ниже печатаются только задействованные имена):

Листинг

>>> import dis

>>> [n for n in dis.opname if n[0] != "<"]

['STOP_CODE', 'POP_TOP', 'ROT_TWO', 'ROT_THREE', 'DUP_TOP', 'ROT_FOUR',

'NOP', 'UNARY_POSITIVE', 'UNARY_NEGATIVE', 'UNARY_NOT', 'UNARY_CONVERT',

'UNARY_INVERT', 'LIST_APPEND', 'BINARY_POWER', 'BINARY_MULTIPLY',

'BINARY_DIVIDE', 'BINARY_MODULO', 'BINARY_ADD', 'BINARY_SUBTRACT',

'BINARY_SUBSCR', 'BINARY_FLOOR_DIVIDE', 'BINARY_TRUE_DIVIDE',

'INPLACE_FLOOR_DIVIDE', 'INPLACE_TRUE_DIVIDE', 'SLICE+0', 'SLICE+1',

'SLICE+2', 'SLICE+3', 'STORE_SLICE+0', 'STORE_SLICE+1', 'STORE_SLICE+2',

'STORE_SLICE+3', 'DELETE_SLICE+0', 'DELETE_SLICE+1', 'DELETE_SLICE+2',

'DELETE_SLICE+3', 'INPLACE_ADD', 'INPLACE_SUBTRACT', 'INPLACE_MULTIPLY',

'INPLACE_DIVIDE', 'INPLACE_MODULO', 'STORE_SUBSCR', 'DELETE_SUBSCR',

'BINARY_LSHIFT', 'BINARY_RSHIFT', 'BINARY_AND', 'BINARY_XOR', 'BINARY_OR',

'INPLACE_POWER', 'GET_ITER', 'PRINT_EXPR', 'PRINT_ITEM', 'PRINT_NEWLINE',

'PRINT_ITEM_TO', 'PRINT_NEWLINE_TO', 'INPLACE_LSHIFT', 'INPLACE_RSHIFT',

'INPLACE_AND', 'INPLACE_XOR', 'INPLACE_OR', 'BREAK_LOOP', 'LOAD_LOCALS',

'RETURN_VALUE', 'IMPORT_STAR', 'EXEC_STMT', 'YIELD_VALUE', 'POP_BLOCK',

'END_FINALLY', 'BUILD_CLASS', 'STORE_NAME', 'DELETE_NAME',

'UNPACK_SEQUENCE', 'FOR_ITER', 'STORE_ATTR', 'DELETE_ATTR', 'STORE_GLOBAL',

'DELETE_GLOBAL', 'DUP_TOPX', 'LOAD_CONST', 'LOAD_NAME', 'BUILD_TUPLE',

'BUILD_LIST', 'BUILD_MAP', 'LOAD_ATTR', 'COMPARE_OP', 'IMPORT_NAME',

'IMPORT_FROM', 'JUMP_FORWARD', 'JUMP_IF_FALSE', 'JUMP_IF_TRUE',

'JUMP_ABSOLUTE', 'LOAD_GLOBAL', 'CONTINUE_LOOP', 'SETUP_LOOP',

'SETUP_EXCEPT', 'SETUP_FINALLY', 'LOAD_FAST', 'STORE_FAST', 'DELETE_FAST',

'RAISE_VARARGS', 'CALL_FUNCTION', 'MAKE_FUNCTION', 'BUILD_SLICE',

'MAKE_CLOSURE', 'LOAD_CLOSURE', 'LOAD_DEREF', 'STORE_DEREF',

'CALL_FUNCTION_VAR', 'CALL_FUNCTION_KW', 'CALL_FUNCTION_VAR_KW',

'EXTENDED_ARG']

Легко

догадаться, что LOAD означает загрузку значения в стек, STORE — выгрузку, PRINT — печать, BINARY — бинарную операцию и т.п.

Отладка

В интерпретаторе языка Python заложены возможности отладки программ, а в стандартной поставке имеется простейший отладчик — pdb. Следующий пример показывает программу, которая подвергается отладке, и типичную сессию отладки:

Листинг

# File myfun.py

def fun(s):

lst = []

for i in s:

lst.append(ord(i))

return lst

Так может выглядеть типичный процесс отладки:

Листинг

>>> import pdb, myfun

>>> pdb.runcall(myfun.fun, «ABCDE»)

> /examples/myfun.py(4)fun

— > lst = []

(Pdb) n

> /examples/myfun.py(5)fun

— > for i in s:

(Pdb) n

> /examples/myfun.py(6)fun

— > lst.append(ord(i))

(Pdb) l

1 #!/usr/bin/python

2 # File myfun.py

3 def fun(s):

4 lst = []

Поделиться:
Популярные книги

Эпоха Опустошителя. Том I

Павлов Вел
1. Вечное Ристалище
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Эпоха Опустошителя. Том I

Проблема майора Багирова

Майер Кристина
1. Спецназ
Любовные романы:
современные любовные романы
6.60
рейтинг книги
Проблема майора Багирова

Законы Рода. Том 13

Андрей Мельник
13. Граф Берестьев
Фантастика:
аниме
фэнтези
5.00
рейтинг книги
Законы Рода. Том 13

Газлайтер. Том 15

Володин Григорий Григорьевич
15. История Телепата
Фантастика:
боевая фантастика
попаданцы
5.00
рейтинг книги
Газлайтер. Том 15

О, Путник!

Арбеков Александр Анатольевич
1. Квинтет. Миры
Фантастика:
социально-философская фантастика
5.00
рейтинг книги
О, Путник!

Прометей: каменный век

Рави Ивар
1. Прометей
Фантастика:
альтернативная история
6.82
рейтинг книги
Прометей: каменный век

Её (мой) ребенок

Рам Янка
Любовные романы:
современные любовные романы
6.91
рейтинг книги
Её (мой) ребенок

Идеальный мир для Лекаря 8

Сапфир Олег
8. Лекарь
Фантастика:
юмористическое фэнтези
аниме
7.00
рейтинг книги
Идеальный мир для Лекаря 8

Прометей: каменный век II

Рави Ивар
2. Прометей
Фантастика:
альтернативная история
7.40
рейтинг книги
Прометей: каменный век II

Цвет сверхдержавы - красный. Трилогия

Симонов Сергей
Цвет сверхдержавы - красный
Фантастика:
попаданцы
альтернативная история
8.06
рейтинг книги
Цвет сверхдержавы - красный. Трилогия

Болтливый мертвец

Фрай Макс
7. Лабиринты Ехо
Фантастика:
фэнтези
9.41
рейтинг книги
Болтливый мертвец

На границе империй. Том 9. Часть 2

INDIGO
15. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 9. Часть 2

Истребители. Трилогия

Поселягин Владимир Геннадьевич
Фантастика:
альтернативная история
7.30
рейтинг книги
Истребители. Трилогия

Лишняя дочь

Nata Zzika
Любовные романы:
любовно-фантастические романы
8.22
рейтинг книги
Лишняя дочь