python局部变量获取_在Python中获取运行时局部变量的名称

Python没有一种可移植的方法来跟踪帧…但是CPython实现可以:^{}返回一个frame对象。在

如何处理帧对象?请参阅^{}文档中的便利图表,了解它的所有有趣之处,但它们包括框架所看到的locals()和{},以及在框架中执行的代码对象,它本身包括本地名称、未绑定名称和闭包单元格。在

但是,正如其他人所指出的那样,您并不真正需要这个框架;您所需要的只是局部变量,而将它显式地传递给上下文管理器要简单得多。在

如果你真的想这么做:import contextlib

import sys

@contextlib.contextmanager

def dumping():

f = sys._getframe(2)

fl = f.f_locals.copy()

try:

yield None

finally:

for name, value in f.f_locals.items():

if name not in fl:

print('{} = {}'.format(name, value))

bar = 0

def foo():

global bar

bar = 3

baz = 4

qux = 5

with dumping():

spam = 'eggs'

eggs = 3

bar = 4

baz = 5

foo()

运行时,应打印:

^{pr2}$

换句话说,只有在with块中声明的新变量的名称和值,我想,这就是您想要的,对吗?在

如果你想要新的和反弹的本地人,你可能想存储这样的东西:fl = {(name, id(value)) for name, value in f.f_locals.items()}

当然,您也可以重新绑定非局部变量和全局变量,因此如果您关心这一点,那么也可以保存全局变量(但请确保检查locals is globals是否为模块级代码),或者执行闭包。在

如果你使用的是cpython2(为什么?对于真正的项目来说,这有时是有意义的,但要了解内部是如何工作的乐趣?但是,有些人…,同样的代码也可以工作。属性名可能稍有不同,但您可以通过转储框架和代码的dir来猜测它们。显然,您需要2.xprint语法。在

它也可以用PyPy,至少2.0b

如果你想知道我是怎么知道使用_getframe(2)的话……我没有。我很确定这会是1或2帧,可能是3帧,但是哪一个呢?所以我就这么做了:@contextlib.contextmanager

def dumping():

for i in range(4):

f = sys._getframe(i)

print(f.f_code.co_filename, f.f_code.co_firstlineno, f.f_lineno)

0当然是dumping本身;1是contextlib.contextmanager中的包装函数;2是调用框架;3是模块顶层。你想一想,这是显而易见的,但直到我知道答案,它才变得明显。:)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值