2012-02-18 1 views
1

Есть ли способ программно найти фрейм, в котором была определена функция? Я ищу что-то вроде функции get_defining_frame, которая будет работать так:Получить объект кадра, который был определен в

def foo(): 
    def bar(): 
     pass 
    return bar 

bar = foo() 

get_defining_frame(foo) # should be the same as inspect.currentframe() 
get_defining_frame(bar) # should be the frame created by the call to foo 

Спасибо!

ответ

0

Рамки создаются/удаляются при каждом вызове функции. Так что, когда вы звоните:

get_defining_frame(bar) 

в вашем примере кода, кадр, где bar был создан уже нет.

Объекты функций не содержат ссылки на фрейм, в котором они были определены. Это хорошо, потому что это позволит освободить все другие локальные переменные.

Зачем вам это нужно?

+0

Мы пытаемся визуализировать код во время его запуска. Я вполне уверен, что этот фрейм еще должен быть доступен, хотя ... если в 'foo' была переменная' x', то вызов 'bar' после того, как этот факт все равно должен был получить доступ к' x', правильно? – user1196203

+0

К 'x', да, но не к кадру, который также упоминается как' x'. Когда локальная переменная ссылается на вложенную функцию, она фактически становится переменной ячейки. Есть дополнительный слой косвенности по сравнению с обычными локальными переменными, именно поэтому объект рамки не должен придерживаться. Переменные ячейки сохраняются в живых (индивидуально), все остальное о объекте фрейма уничтожается. –

0

Вы не можете получить такую ​​информацию, если не будете хранить ее самостоятельно (возможно, декоратор). Посмотрите на bar.__code__ и bar.__closure__, возможно, они предоставят вам достаточно информации. __closure__ не сохранит весь контекст для создания бара, а только переменные, на которые ссылается панель для соображений эффективности памяти.

декоратор, который должен сделать трюк:

def save_frame(func): 
    frame=inspect.currentframe().f_back 
    func.__frame = frame 
    return func 

Имейте в виду, что использование этого действительно запутались вывоз мусора, хранение весь кадр стека ничего не значит, на который ссылается где-нибудь в стеке может быть GC-эд (поэтому __closure__ только фиксирует то, что упоминается).