给定框架对象(例如,由sys._getframe返回),我可以获得底层的可调用对象吗?
代码说明:
def foo():
frame = sys._getframe()
x = some_magic(frame)
# x is foo, now
Run Code Online (Sandbox Code Playgroud)
请注意,我的问题是将对象移出框架,而不是当前调用的对象。
希望这是可能的。
干杯,
MH
编辑:
我在某种程度上设法解决了这个问题。它深受 Andreas 和 Alexander 答复的启发。感谢大家投入的时间!
def magic():
fr = sys._getframe(1)
for o in gc.get_objects():
if inspect.isfunction(o) and o.func_code is fr.f_code:
return o
class Foo(object):
def bar(self):
return magic()
x = Foo().bar()
assert x is Foo.bar.im_funcRun Code Online (Sandbox Code Playgroud)
(在2.6.2工作,为py3k替换func_code用__code__,并im_func用__func__)
然后,我可以积极地遍历 globals() 或 gc.get_objects() 和 dir() 一切以搜索具有给定函数对象的可调用对象。
对我来说感觉有点 unpythonic,但有效。
再次感谢!
MH
为了支持所有情况,包括函数作为类的一部分或只是全局函数,没有直接的方法来执行此操作。您也许能够获得完整的调用堆栈并向下迭代globals(),但这不太好......
我能给你的最接近的是:
import sys, types
def magic():
# Get the frame before the current one (i.e. frame of caller)
frame = sys._getframe(1)
# Default values and closure is lost here (because they belong to the
# function object.)
return types.FunctionType(frame.f_code, frame.f_globals)
class MyClass(object):
def foo(self, bar='Hello World!'):
print bar
return magic()
test = MyClass()
new_foo = test.foo()
new_foo(test, 'Good Bye World!')
Run Code Online (Sandbox Code Playgroud)
您将执行完全相同的代码,但它将位于新的代码包装器中(例如FunctionType。)
我怀疑您希望能够基于堆栈恢复应用程序的状态...这是至少会尽可能与原始调用类似地调用函数的东西(闭包仍然被忽略,因为如果您可以从框架中获取闭包,获取被调用的函数将非常容易):
import sys, types
class MyClass(object):
def __init__(self, temp):
self.temp = temp
def foo(self, bar):
print self.temp, bar
return sys._getframe()
def test(hello):
print hello, 'World!'
return sys._getframe()
def recall(frame):
code = frame.f_code
fn = types.FunctionType(
code, frame.f_globals, code.co_name,
# This is one BIG assumption that arguments are always last.
tuple(frame.f_locals.values()[-code.co_argcount:]))
return fn()
test1 = MyClass('test1')
frame1 = test1.foo('Hello World!')
test2 = MyClass('test2')
frame2 = test2.foo('Good Bye World!')
frame3 = test2.foo('Sayonara!')
frame4 = test('HI')
print '-'
recall(frame4)
recall(frame3)
recall(frame2)
recall(frame1)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1520 次 |
| 最近记录: |