2017-09-06 2 views
2

Je viens de passer près d'une heure à rechercher ce qui était - à l'époque - un message d'erreur très confus. La source de l'erreur était ce bloc de code (aux fins de cette question, le sens de toutes les pièces n'a pas d'importance):Évitez d'être mordu par un espace de noms contaminé

fspec_prsrs = tuple(compile('{{{}{}}}'.format(fstr_tup.field_name 
               if fstr_tup.field_name else '', 
               ':'+fstr_tup.format_spec 
               if fstr_tup.format_spec else '' 
              ) 
          ) 
        for fstr_tup in fstr_tuples) 

Ce qui a donné lieu à cette erreur:

*** TypeError: Required argument 'filename' (pos 2) not found 

La cause de l'erreur est que j'ai négligé de faire une importation de la fonction compile en haut du fichier (à partir du parse module). Par conséquent, compile fait référence à built-in compile function. Bien que le message d'erreur me semble très clair maintenant que je comprends la cause, j'ai perdu beaucoup de temps à regarder le code source du paquet à partir duquel pensait J'avais importé la fonction, pensant que l'erreur venait de là. Au lieu de cela, il venait de la compile intégré tout au long.

La fonction compile est quelque chose que j'ai tendance à oublier même s'il existe. Je l'utilise presque jamais, si jamais, et en effet il y a un certain nombre de fonctions dans la liste intégrée, tout comme compile que j'utilise également jamais (je regarde VOUS, id et VOUS, filter!), Et par conséquent ils sont assis là à ne rien faire d'autre que de contaminer mon espace de noms.

Typiquement, lorsque vous oubliez d'importer quelque chose, vous obtenez simplement NameError, auquel cas la cause est évidente; mais quand il y a des choses qui se cachent dans l'espace de noms que je n'ai pas mis là, c'est beaucoup moins évident. Existe-t-il un moyen complet d'éviter les problèmes de ce genre?

Que peut-on faire? Ou est-ce juste quelque chose que chaque codeur Python doit apprendre à vivre avec?

+1

Peut-être utiliser un IDE qui met en évidence les noms intégrés? De cette façon, il sera clair si votre code fait référence à un nom intégré. Pycharm le fait. Ainsi que Sublime. –

+0

@ChristianDean Puisque je n'ai jamais utilisé régulièrement un IDE cette solution ne m'était pas évidente, même si je suis sûr que cela semble évident pour les gens qui l'ont fait. J'ai généralement dit "je n'ai pas besoin d'un IDE" (j'utilise simplement Notepad ++) mais je suppose que ce soir j'ai prouvé que je le faisais. –

Répondre

2

La seule idée que j'ai qui évite ce problème est de ne pas importer d'objets dans l'espace de noms pour commencer. Par exemple, au lieu de:

from parse import compile 

On pourrait faire:

import parse 
parse.compile(...) 

Cela corrige le problème. Cependant, je n'aime pas cette solution parce que la seule chose que je prévois d'utiliser du paquet parse dans ce module est compile en premier lieu. C'est un peu plus direct et clair pour le lecteur (par exemple, Future Me) POURQUOI et QU'EST-CE QUE Je fais usage du module parse lorsque ce qui est importé est juste à l'avant.

Une meilleure solution serait de "régler et oublier" pour éliminer les choses de l'espace de noms global qui ne me sont pas utiles dans le module dans lequel je travaille.

+0

serait 'd'importation d'analyse compiler comme ' être adapté à la compréhension du futur vous? – Eric

+0

@Eric je ne sais pas ... avenir moi est assez stupide. C'est une bonne suggestion en général, mais ma plainte serait que, pour * se souvenir * j'ai besoin de faire cela, je devrais être conscient - * aujourd'hui * - de la pollution de l'espace de noms de bulit-in en premier lieu ... manque de cette attention était la source du problème pour commencer. –

+0

'from import ' est un motif relativement facile à grap, donc vous pouvez scanner automatiquement votre code pour ce genre d'aberration. Ou vous pouvez même écrire un plugin pour [Pylint] (https://pylint.readthedocs.io/en/latest/how_tos/plugins.html). – Eric