aar*_*ing 6 python python-internals
我正在编写一些代码来确定分配对象的名称.这是一般调试工作,并进一步熟悉python内部.
我将它结构化为类装饰器,以便在可能的情况下,该类的所有实例都将记录其名称.代码相当长,所以除非被问到,否则我不会发布.一般技术如下
__init__用代码装饰类的方法来做我想做的事
设置caller = inspect.currentframe().f_back并打开inspect.getframeinfo(caller).filename并发送给ast.parse.我没有在这里做任何错误检查,因为(1)这只是用于调试/分析/黑客攻击(2)这个确切的过程"刚刚"完成或代码不会运行.这有问题吗?
找到ast.Assignment导致当前正在执行的__init__方法运行的实例
如果len(assignment.targets) == 1那时左侧只有一个项目,我可以从中获取名称targets[0].id.在一个简单的形式a = Foo(),然后assignment.value是一个实例ast.Call.如果它是文字(例如列表),那么value将是该列表和保释,因为我感兴趣的对象没有被分配给名称.
确认这assignment.value.func是type(obj).__call__我感兴趣的对象的最佳方法是什么.我很确定我保证它"在某处"或者代码甚至不会运行.我只需要它在顶级.显而易见的事情是走它并确保它不包含任何内部调用.然后我保证我有名字.(我的推理是正确的,我不确定它的假设是否正确).这并不理想,因为如果我感兴趣Foo,这可能会导致我抛弃,a = Foo(Bar())因为我不知道是不是a = Bar(Foo()).
当然我可以检查,assignment.value.func.id但后来有人可以做Foobar = Foo或什么,所以我不想太依赖这个
任何帮助将不胜感激.一如既往,我对我可能忽略的任何其他建议或问题感兴趣.
另外,我真的很惊讶我只需要发明'python-internals'标签.
小智 2
AST 无法给你这个答案。尝试使用frame.f_lasti,然后查看字节码。如果下一行不是 STORE_FAST,那么除了您正在寻找的简单分配之外,您还进行了内部调用或其他操作。
def f():
f = sys._getframe()
i = f.f_lasti + 3 # capture current point of execution, advance to expected store
print dis.disco(f.f_code, i)
Run Code Online (Sandbox Code Playgroud)