Python中获取指定位置后新定义变量的问题及解决方法
How to Isolate Variables Defined After a Certain Point in Python?
问题出在哪里?
你的代码有两个关键问题导致不符合预期:
beginning变量本身会被加入全局作用域:当你执行beginning = deepcopy(dict(globals()))时,右边的dict(globals())确实获取了赋值前的全局状态,但赋值完成后,beginning这个变量会被自动添加到全局命名空间中。后续调用globals()时会包含这个变量,所以你的字典推导式会把beginning也纳入end的结果里。- 交互式环境的历史变量干扰(如果是在交互模式下运行):如果你在Python交互式shell中执行这段代码,之前会话中定义过的变量也会存在于
globals()中,导致end包含更多非预期变量。
你提到“实际获取了整个作用域的内容”,大概率是因为end里包含了beginning和a,加上你可能误将原有全局变量(比如__name__、__doc__)当成了新增变量,但实际上原有变量的键应该存在于beginning中,不会被纳入end——你可以仔细检查end的内容,会发现它只包含beginning和a这两个新增变量。
如何实现预期效果?
我们需要排除掉beginning这个快照变量本身,只保留我们真正关心的新增变量。这里有两种简洁的实现方式:
方式一:提前排除快照变量
在创建初始快照时,提前过滤掉即将创建的beginning变量名(因为赋值后它才会加入全局作用域,所以初始快照里本来就没有它,不过后续对比时需要明确排除):
from copy import deepcopy # 获取初始全局变量快照 beginning = deepcopy(dict(globals())) a = 5 # 新增其他变量... # 生成结果时,排除初始快照里的变量,同时排除快照变量本身 end = { k: v for k, v in dict(globals()).items() if k not in beginning and k != "beginning" } print(end) # 输出: {'a': 5}
方式二:使用集合差集简化逻辑
先获取初始和后续的全局变量键集合,通过差集直接得到新增的变量名,再生成结果字典:
from copy import deepcopy beginning_keys = set(dict(globals()).keys()) a = 5 # 新增其他变量... current_keys = set(dict(globals()).keys()) # 计算新增的键:排除初始键,同时排除存储初始键的变量名 new_keys = current_keys - beginning_keys - {"beginning_keys"} end = {k: globals()[k] for k in new_keys} print(end) # 输出: {'a': 5}
额外提示
- 如果只是对比变量名的存在,
deepcopy其实是没必要的——因为我们只关心键(字符串),浅拷贝dict(globals())就足够了,使用deepcopy只会增加不必要的开销。 - 如果你是在脚本文件中运行代码,而非交互式环境,上述方法可以精准捕获你在快照后定义的所有变量。
内容的提问来源于stack exchange,提问作者Ma0
相关产品推荐
相关产品推荐

