Определение вызова функции в строке скрипта Python во время выполнения - PullRequest
2 голосов
/ 13 мая 2010

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

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

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)())

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

Ответы [ 2 ]

1 голос
/ 14 мая 2010

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

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

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

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

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

и затем выполните аннотированный код.

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

0 голосов
/ 14 мая 2010

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

bar = foo2
foo1(); foo2()

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

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

...