2010-05-13 2 views
2

У меня есть сценарий python, который я запускаю с помощью «exec». Когда функция вызывается скриптом, я хотел бы, чтобы он знал номер строки и смещение в строке для этого вызова.Идентификация вызова функции в строке сценария python во время выполнения

Вот пример. Если мой сценарий:

foo1(); foo2(); foo1() 
foo3() 

И если у меня есть код, который печатает (линия, смещение) в каждой функции, я должен получить

(0,0), (0,8), (0,16), (1,0) 

В большинстве случаев это можно легко сделать, получив стек поскольку он содержит номер строки и имя функции. Единственная проблема в том, что в одной строке есть две функции с одним и тем же именем. К сожалению, это общий случай для меня. Есть идеи?


ОК кажется, что изменение исходного кода является самым простым решением.

Как бы вы решить такие вещи, как

if foo1(7) or foo1(6): 

или

foo2(foo1(), foo1()) 

Есть некоторые не очень элегантные решения для этого, например, автоматически поворачивая предыдущий пример:

def curpos(pos, func): 
    record_curpos(pos) 
    return func 

curpos(foo2,0)(curpos(foo1,5)(), curpos(foo1,13)()) 

Дайте мне знать, если у вас есть более простые идеи.

ответ

1

Python не предоставляет много информации о смещениях символов в строке.

Если вы используете exec для выполнения Python, вы можете переписать код механически, прежде чем выполнять его, чтобы сообщить вам, что вы хотите знать. Например, вы можете изменить исходный код:

foo1(); foo2(); foo1() 
foo3() 

в аннотированный код:

curpos(1,0); foo1(); curpos(1,8); foo2(); curpos(1,16); foo1() 
curpos(2,0); foo3() 

, а затем EXEC аннотированный код.

Где curpos(line,char) записывает или печатает информацию о линии и символах этой точки в исходном коде. Это будет намного проще, чем сбрасывать фреймы стека.

0

Конечно, вы можете посмотреть на линии в строке, и попытаться найти имя функции, хотя это не будет надежной, если они псевдоним функции, например:

bar = foo2 
foo1(); foo2() 

В противном случае он получает очень трудно , Модуль coverage делает это, и Нед объяснил конкретную технику in a blog post - в основном это связано с переписыванием байт-кода для выделения выражений в разные (поддельные) номера строк.

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

+0

Собственно, переписывание байт-кода было в другом сообщении: http://nedbatchelder.com/blog/200804/wicked_hack_python_bytecode_tracing.html (мне не приходилось прибегать к этому, чтобы получить охват филиала). –

+0

Спасибо! выглядит очень актуальным (и интересным) – Dani

Смежные вопросы