2010-01-13 4 views
1

Comment savoir quel module/package membres est défini? En définissant je veux dire:Tous les membres package/module définit?

somemodule.py

import os # <-- Not defined in this module 
from os.path import sep # <-- Not defined in this module 

I_AM_ATTRIBUTE = None # <-- Is defined in this module 

class SomeClass(object): # <-- Is defined also... 
    pass 

donc j'ai besoin d'une certaine sorte de fonction que lorsqu'elle est appelée produirait que I_AM_ATTRIBUTE et SomeClass.

Maintenant, j'ai essayé de faire en utilisant dir(somemodule), mais comment puis-je savoir lesquels sont définis dans somemodule? La vérification par rapport à __module__ ne fonctionne pas, car elle n'est pas définie dans les modules et les attributs (tels que le package os ou l'attribut sep).

Apparemment, l'importation sauvage (from somemodule import *) ne permet pas non plus de filtrer ceux-ci, est-ce même possible?

Le meilleur que je peux obtenir est:

import somemodule 

for name in dir(somemodule): 
    try: 
     value = getattr(somemodule, name) 
    except: 
     pass 
    else: 
     if hasattr(value, "__module__"): 
      if value.__module__ != somemodule.__name__: 
       continue 
     if hasattr(value, "__name__"): 
      if not value.__name__.startswith(__name__): 
       continue 
     print "somemodule defines:", name 

Prend os, mais laisse sep.

+1

Quel est le problème avec la lecture de la source? Vous pouvez trivialement comprendre cela en lisant? Pourquoi ne pas simplement lire? –

Répondre

1

Que signifie "définir"? Pour moi, défini signifie que certains symboles font partie de l'interface publique du module. Cela correspond à la façon dont il semble que vous essayez d'utiliser le terme, y compris dans votre exemple, mais si vous avez un but qui ne correspond pas à cette définition, vous devrez clarifier la question sur ce que vous êtes vraiment essayer de faire. Cela fait un problème de documentation. Vous ne pouvez donc pas savoir ce qu'un module définit, et certaines choses qui sont importées peuvent encore être "définies dans ce module" ou "définies pour faire partie de l'interface publique de ce module". Cela arrive souvent lors de l'importation à partir d'un module privé, y compris les modules d'extension C.

Pour vos propres modules, utilisez __all__ (peut le faire easily) ou le préfixe underscore informel pour les non-publics (par exemple _private_var = 42). Les deux conventions sont reconnues par help() et devraient être utilisées par d'autres générateurs de documentation.

+0

Hé, je parie que vous avez lu ma question précédente ...Puisque j'essaie de faire du générateur de documentation (en fait en améliorant Sphinx) pour faire de la documentation automatique sur les paquets, et de réfléchir au fait que si le module n'a pas '__all__', quels documents devrions-nous documenter? Je termine probablement d'utiliser le code ci-dessus * si * '__all__' n'est pas défini ... Il supprime au moins le" os "et de telles importations. – Ciantic

+0

Non, en fait je ne l'avais pas lu, mais j'ai essayé de savoir ce que vous * vouliez vraiment faire plutôt que d'essayer de réparer votre solution. :) –

+0

S'il n'y a pas de \ _ \ _ all \ _ \ _, documentez tout ce qui ne commence pas par un trait de soulignement, et demandez à l'auteur d'ajouter \ _ \ _ all \ _ \ _ si ce n'est pas ce qui est souhaité. Si vous voulez ajouter des notices comme "(ceci est probablement un détail d'implémentation)" pour des choses que vous pouvez détecter, comme des modules importés, c'est aussi raisonnable, mais il est difficile de dire si elles font partie de l'interface. (Par exemple, os.path fait partie de l'interface, mais est un module séparé.) –

1

Il n'y a aucun moyen de le faire. En effet, les attributs simples (comme I_AM_ATTRIBUTE dans votre exemple) sont simplement des valeurs stockées dans le dictionnaire du module. Quand ils sont copiés dans un autre module, ils sont également placés dans le dictionnaire de ce module, et il n'y a aucun moyen de savoir quel était l'emplacement d'origine. Vous ne pouvez indiquer aux objets qui fournissent un attribut __module__ que des classes et des fonctions. En ce qui concerne l'importation sauvage, l'exécution de from somemodule import * sur votre exemple importera tous les attributs, y compris os et sep. Si un paquet fournit une variable __all__, l'importation sauvage importera les noms qui y sont contenus. Sinon, il importera tous les noms ne commençant pas par un trait de soulignement, quel que soit le module d'origine.

+0

J'ai édité la question, j'ai également trouvé que "os" peut être laissé de si vérifié en utilisant '__name__'. – Ciantic

Questions connexes