2017-01-25 3 views
1

Aujourd'hui, je suis tombé sur l'erreur pylint suivante:Pourquoi est-ce que __all__ ne doit contenir que des objets chaîne?

invalid-all-object (E0604):

Invalid object %r in __all__, must contain only strings Used when an invalid (non-string) object occurs in __all__.

Et je suis assez curieux de savoir pourquoi il est considéré comme incorrect d'exposer des objets directement?

Répondre

5

Parce qu'il est censé être une liste de noms , non valeurs:

If the list of identifiers is replaced by a star ('*'), all public names defined in the module are bound in the local namespace for the scope where the import statement occurs.

The public names defined by a module are determined by checking the module’s namespace for a variable named __all__ ; if defined, it must be a sequence of strings which are names defined or imported by that module. The names given in __all__ are all considered public and are required to exist. If __all__ is not defined, the set of public names includes all names found in the module’s namespace which do not begin with an underscore character ('_'). __all__ should contain the entire public API. It is intended to avoid accidentally exporting items that are not part of the API (such as library modules which were imported and used within the module). [ Language Reference ]

3

Si vous exposez autre chose qu'une chaîne, Python lèvera une exception. C'est pourquoi pylint donne cette erreur, car le code est incorrect.

fichier mymodule.py:

def func(): 
    pass 
__all__ = [func] 

Exécuter maintenant:

from mymodule import * 

Vous obtiendrez un TypeError.

 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: attribute name must be string, not 'function' 

La raison est que __all__ est utilisé pour nommer les attributs de l'objet module. C'est juste comment le mécanisme fonctionne. Si vous vouliez modifier le mécanisme d'importation de Python pour y placer des objets, je suppose que vous le pourriez, mais cela ne fonctionnerait qu'avec certains types d'objets (les fonctions et les classes fonctionneraient, mais les constantes ne fonctionneraient pas, et vous ne le feriez pas être capable de renommer les fonctions et les classes).