2017-07-25 1 views
0

Cela semble étrange. Une variable avec un nom classes est imprimée mais n'est pas définie lors de la tentative d'exécution de la contruction filter(...).PDB: La variable peut être imprimée mais n'est pas définie

Voici un code:

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 arrête sur son pause. Lorsque je tente d'exécuter filter():

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

Mais:

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

Pourquoi l'instruction filter(...) ne pouvait pas être exécutée normalement?

Nous allons reproduire dans le code court:

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 

Cependant, la commande c (continue) de pdb au point a ne génère pas une exception.

+0

On dirait que vous avez probablement fait une faute de frappe dans votre code réel et corrigé la faute de frappe sans remarquer lorsque vous avez posté cette question. – user2357112

+0

(Ce 'n'a pas de sens, d'ailleurs, votre prédicat retourne un objet' partial' au lieu d'un booléen.) – user2357112

+0

@ user2357112 Bonjour. C'est ce que dans mon code maintenant. – sergzach

Répondre

1

pdb est une boucle eval. Une boucle d'évaluation prend essentiellement ce que vous écrivez à l'invite ligne par ligne et eval(...) s il. Cela signifie qu'il ne lie pas les variables délimitées par la fermeture dans les fonctions définies (lambdas). eval (qui est une fonction) a sa propre portée et ne participe pas à la fermeture que vous évaluez dans

Vous pouvez voir le problème équivalent de cet exemple de code.

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 

Un (malheureux) solution de contournement consiste à définir tout lambdas à l'avance et les utiliser dans votre expression pdb.