2017-10-19 13 views
1

Je veux accéder à un type de suivi de dépendance d'importation en Python, s'il y en a.Comment obtenir la liste des modules importés par un module python

J'ai décidé d'ajouter à mon module un __dependencies__ décrivant les versions de tous les modules importés par le module.

Je veux avoir un moyen automatisé d'obtenir une liste de modules importés par mon module. De préférence dans la dernière ligne du module.

ModuleFinder (comme suggéré par How to list imports within a Python module?) ne fonctionnerait pas puisque l'inspection doit être effectuée pour un module déjà chargé.

Un autre problème avec ModuleFinder est qu'il inspecte un script Python (avec if __name__ == '__main__' branche), pas un module.

Si l'on considère un script de jouet script.py:

if __name__ == '__main__': 
    import foo 

alors le résultat est:

>>> mf = ModuleFinder 
>>> mf.run_script('script.py') 
>>> 'foo' in mf.modules 
True 

qui devrait être faux si le script est importé en tant que module.

Je ne veux pas lister tous les modules importés - seulement les modules importés par mon module - donc sys.modules (suggéré par What is the best way of listing all imported modules in python?) retournerait trop.

Je peux comparer les instantanés de sys.modules depuis le début et la fin du code du module. Mais de cette façon tous les modules utilisés par mon module me manqueraient, mais importés auparavant par n'importe quel autre module.

Il est important de répertorier également les modules à partir desquels le module importe des objets.

Si l'on considère un module de jouet example.py:

from foo import bar 
import baz 

alors le résultat devrait être comme:

>>> import example 
>>> moduleImports(example) 
{'foo': <module 'foo' from ... >, 
'baz': <module 'baz' from ...>} 

(il peut contenir aussi des modules importés barre récursive ou foo.bar donné est un module).

Utilisation de globls() (selon How to list imported modules?) me oblige à traiter les importations non-modules manuellement, comme:

from foo import bar 
import bar 

Comment puis-je éviter cela?

Il existe un autre problème avec ma solution jusqu'à présent. PyCharm a tendance à nettoyer mes importations manuelles sur le refactoring, ce qui rend difficile le fonctionnement.

+0

Il n'est pas clair pourquoi vous pensez que 'ModuleFinder' ne fonctionnerait pas. En fait, il doit sûrement être la seule chose qui pourrait fonctionner. Sinon, comment allez-vous faire la différence entre les modules déjà chargés et ceux qui ont d'abord été importés par votre module? Et comment identifieriez-vous les importations qui ne sont pas dans la portée globale du module (par exemple, dans les fonctions internes)? – ekhumoro

+0

@ekhumoro Je ne sais pas pourquoi SO ne m'a pas informé de votre commentaire. Voir la question éditée, alors s'il vous plaît faites le moi savoir que je peux supprimer [EDIT] tags. – abukaj

+0

Votre affirmation selon laquelle 'ModuleFinder' ne fonctionne pas avec les modules est évidemment fausse - voir [l'exemple dans les docs python] (https://docs.python.org/2/library/modulefinder.html#example-usage-of- modulefinder). Je ne vois pas d'autres bonnes raisons pour lesquelles vous ne devriez pas l'utiliser. – ekhumoro

Répondre

0

Vous pouvez utiliser le inspect moudule

Par exemple:

import inspect 
import os 
m = inspect.getmembers(os) # get module content 
filter(lambda x: inspect.ismodule(x[1]), m) # filter dependant modules 

Ici vous avez un live example

Si vous voulez que les modules locaux importés simplement utiliser:

filter(lambda x: inspect.ismodule(x[1]), locals().items()) # filter dependant modules 

Un autre live example

+0

Merci. Malheureusement, il a le même inconvénient que ma solution actuelle (filtrage 'globals()'). Il omet les importations hors module (dans le cas de '' depuis la barre d'importation de foo' 'foo' passe inaperçu). – abukaj

+0

@abukaj, je ne pense pas que vous l'obtiendrez à moins d'une spécification manuelle, parce que foo n'est pas utilisé car python ne l'amène pas à la portée:/ – Netwave

+0

J'espérais qu'il y ait une sorte de suivi d'import dans les modules Python. – abukaj