2017-07-25 31 views
0

看起来很奇怪。打印名称为类别的变量会被打印,但在尝试执行filter(...)建筑时未定义。PDB:变量可以打印但未定义

下面是一个代码:

def start(self, tag, attrib): 
    classes = attrib[self._CLASS_ATTR] if self._CLASS_ATTR in attrib else None 

    if tag == self._TAG_P: 
     p = self._doc.add_paragraph('') 

     self._cur_p = p 

     if classes is not None: 
      alignments = [self._left_align, self._center_align, self._right_align] 
      import pdb; pdb.set_trace() 
      alignments = filter(lambda x: partial(x.is_in, classes), alignments) 
      if len(alignments) > 0: 
       p.alignment = alignments[0].get() 

      assert len(alignments) < 2 

PDB停止在其上的突破。当我尝试执行filter()

(Pdb) print filter(lambda x: partial(x.is_in, classes), alignments) 
*** NameError: global name 'classes' is not defined 

但是:

(Pdb) print classes 
center title 
(Pdb) classes 
u'center title' 

为什么filter(...)指令不能正常执行?

让我们重现它在短代码:

from functools import partial 

def f(): 
    classes = 'my_classes' 

    def my_bool(obj, _): 
     return True 

    if classes is not None: 
     import pdb; pdb.set_trace() # point a 
     alignments = filter(lambda x: my_bool(x, classes), ['1', '2', '3']) 
     import pdb; pdb.set_trace() # point b 
     pass 

f() 

... 

(Pdb) filter(lambda x: my_bool(x, classes), ['1', '2', '3']) 
*** NameError: global name 'my_bool' is not defined 

但是,命令c PDB的(继续)在点a不会产生异常。

+0

听起来像你可能在你的真实代码中犯了一个错误,并且在你发布这个问题时没有注意到错误。 – user2357112

+0

(顺便说一下'filter'没有任何意义,你的谓词返回一个'partial'对象而不是布尔值。) – user2357112

+0

@ user2357112你好。这就是我现在的代码。 – sergzach

回答

1

pdbeval循环。一个eval循环基本上将你所写的内容写入提示行并按照它的顺序排列。这意味着它不会在已定义函数(lambdas)中绑定闭包范围变量。 eval(这是一个功能),有它自己的范围,不参加你正在评估的封闭

你可以看到从这个例子的代码等价问题:

def f(): 
    x = 1 
    return eval('lambda: x') 

>>> f()() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<string>", line 1, in <lambda> 
NameError: name 'x' is not defined 

的(不幸的)解决方法是先定义任何lambda表达式并在您的pdb表达式中使用它们。