2017-07-25 47 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表達式中使用它們。