Python ';名称错误:未定义全局名称';在pdb下,对于确实存在的字典

Python ';名称错误:未定义全局名称';在pdb下,对于确实存在的字典,python,lambda,pdb,nameerror,Python,Lambda,Pdb,Nameerror,我在lambda函数的作用域中遇到了一个问题。我可以成功地将foo输出到stdout,但使用max()时出错,包括lambda-请参阅下面的简化代码 总之,我正在尝试在未知数量的一阶键中查找嵌套键budget的最大值 (Pdb) foo = self.some_method() # some_method() returns a dict, printed in the next step (Pdb) pp foo {'1': {'count': 1, 'extra_da

我在
lambda
函数的作用域中遇到了一个问题。我可以成功地将foo输出到stdout,但使用
max()
时出错,包括
lambda
-请参阅下面的简化代码

总之,我正在尝试在未知数量的一阶键中查找嵌套键
budget
的最大值

(Pdb) foo = self.some_method()    # some_method() returns a dict, printed in the next step

(Pdb) pp foo

{'1': {'count': 1,
       'extra_data': {'activity-count': 1,
                             'budget': 0,
                             [...MORE KEY-VALUE PAIRS HERE...]
                             'version': 1},
       [...LOTS MORE KEY-VALUE PAIRS HERE...]
       'elements_total': defaultdict(<type 'int'>, {'result': 1, 'another_key': 2}),
       'extra_year_data': defaultdict(<function <lambda> at 0x10e05bd70>, {})}, 

 '2': {'count': 1,
       'extra_data': {'activity-count': 1,
                             'budget': 3,
                             [...MORE KEY-VALUE PAIRS HERE...]
                             'version': 1},
       [...LOTS MORE KEY-VALUE PAIRS HERE...]
       'elements_total': defaultdict(<type 'int'>, {'result': 1, 'another_key': 2}),
       'extra_year_data': defaultdict(<function <lambda> at 0x10e05bd70>, {})}}

(Pdb) max(foo, key=lambda x: foo[x]['extra_data']['budget'])
*** NameError: global name 'foo' is not defined
(Pdb)foo=self.some_method()#some_method()返回一个dict,在下一步中打印
(Pdb)pp foo
{'1':{'count':1,
'extra_data':{'activity-count':1,
“预算”:0,
[…这里有更多的键值对…]
“版本”:1},
[…这里有更多的键值对…]
'elements_total':defaultdict(,{'result':1,'另一个_键]:2}),
“额外年份数据”:defaultdict(,{}),
'2':{'count':1,
'extra_data':{'activity-count':1,
"预算":3,,
[…这里有更多的键值对…]
“版本”:1},
[…这里有更多的键值对…]
'elements_total':defaultdict(,{'result':1,'另一个_键]:2}),
“额外年份数据”:defaultdict(,{}}
(Pdb)最大值(foo,key=lambda x:foo[x][‘额外数据’][‘预算’)
***NameError:未定义全局名称“foo”
总之,我试图使用
max(foo,key=lambda x:foo[x]['extra_data']['budget'])
在未知数量的一阶键中查找嵌套键
budget
的最大值

这种情况下的预期结果可能是
2
作为
foo['2']['extra_data']['budget']=3
vs.
foo['1']['extra_data']['budget']=0

该错误是否与某些(不相关的)键中包含
defaultdict
有关?

您使用
pdb
设置了一个新的本地键,但此调试器会话中使用嵌套作用域的表达式无法看到该错误。嵌套作用域中的任何表达式(如用于
key
参数的
lambda
)都需要是闭包,并且会出现此问题

这是调试器和Python编译工作方式的限制;只有在需要生成闭包的函数在同一会话中编译时,才能创建闭包。由于您正在调试的函数在编译时没有将
foo
作为闭包,因此
lambda
表达式本身不能使用它

可以将本地绑定到lambda(使其成为本地而不是闭包):


有关Python编译器如何创建闭包的详细信息,请参阅。

有一个(但是这个问题影响到Python 2.7,正如您所发现的那样)建议使用a作为Martijn解决方案的替代方案:
interactive
pdb
提示符处将您放入一个交互式会话,该会话由
globals()填充
locals()
以及您的
lambda
应该能按预期工作。

这会影响您的全局范围,但在使用python 2.7时,我使用了一种快速(肮脏)的解决方法:

globals().update(locals())

我可能误解了你们所说的环境是什么意思,但那个是在Mac10.10.1 Yosemite上的Python2.7.6终端上用pdb运行的。不,用过了。我所需要的只是更多的咖啡因。为什么不
max(foo.values(),key=lambda x:x['extra_data']['budget'])
?谢谢,我想我现在明白了。这是否意味着当我将其添加到脚本中时,我不需要将本地绑定到lambda-也就是说,我可以使用
max(foo,key=lambda x:foo[x]['extra_data']['budget'])
?@user2761030:抱歉,请重试。是的,您可以将其添加到脚本中,因为Python编译器随后会在使用的
lambda
中看到名称
foo
,所以它将在父范围中创建闭包。那就行了。你不能在
pdb
中这样做。我也曾在python3.6中工作过
globals().update(locals())