web-dev-qa-db-fra.com

Construire un graphe d'appel en python incluant les modules et les fonctions?

J'ai un tas de scripts pour effectuer une tâche. Et j'ai vraiment besoin de connaître le graphe d'appel du projet car c'est très déroutant. Je ne suis pas en mesure d'exécuter le code car il a besoin de matériel et de logiciels supplémentaires pour ce faire. Cependant, je dois comprendre la logique derrière cela. Donc, j'ai besoin de savoir s'il existe un outil (qui ne nécessite aucun python)) qui peut construire un graphe d'appel en utilisant les modules au lieu de la trace ou python analyseur. J'ai de tels outils pour C mais pas pour python.
Je vous remercie.

46
JohnnyDH

Le meilleur outil que j'ai trouvé s'appelle pyan, et était écrit à l'origine par Edmund Horner , amélioré par lui , et alors colorisation donnée et autres fonctionnalités par Juha Jeronen . Cette version a des options de ligne de commande utiles:

Usage: pyan.py FILENAME... [--dot|--tgf]

Analyse one or more Python source files and generate an approximate call graph
of the modules, classes and functions within them.

Options:
  -h, --help           show this help message and exit
  --dot                output in GraphViz dot format
  --tgf                output in Trivial Graph Format
  -v, --verbose        verbose output
  -d, --defines        add edges for 'defines' relationships [default]
  -n, --no-defines     do not add edges for 'defines' relationships
  -u, --uses           add edges for 'uses' relationships [default]
  -N, --no-uses        do not add edges for 'uses' relationships
  -c, --colored        color nodes according to namespace [dot only]
  -g, --grouped        group nodes (create subgraphs) according to namespace
                       [dot only]
  -e, --nested-groups  create nested groups (subgraphs) for nested namespaces
                       (implies -g) [dot only]

Voici le résultat de l'exécution de pyan.py --dot -c -e pyan.py | fdp -Tpng:

pyan's output on itself

Le code original d'Edmund Horner est maintenant mieux trouvé dans son référentiel github , et quelqu'un a également créé un référentiel avec les deux versions , d'où vous pouvez télécharger la version de Juha Jeronen . J'ai fait une version propre combinant leurs contributions dans mon propre référentiel juste pour pyan , car les deux référentiels ont beaucoup d'autres logiciels.

35
David Fraser

Vous voudrez peut-être consulter pycallgraph:

pycallgraph

Dans ce lien également, une approche plus manuelle est décrite:

générer-graphes-d'appel-pour-comprendre-et-refactoriser-code-python

26
vkontori

Bref, un tel outil n'existe pas. Python est beaucoup trop dynamique d'un langage pour pouvoir générer un graphe d'appel sans exécuter le code.

Voici du code qui illustre clairement certaines des fonctionnalités très dynamiques de python:

class my_obj(object):
    def __init__(self, item):
        self.item = item
    def item_to_power(self, power):
        return self.item ** power

def strange_power_call(obj):
    to_call = "item_to_power"
    return getattr(obj, to_call)(4)

a = eval("my" + "_obj" + "(12)")
b = strange_power_call(a)

Notez que nous utilisons eval pour créer une instance de my_obj et également en utilisant getattr pour appeler une de ses méthodes. Ce sont deux méthodes qui rendraient extrêmement difficile la création d'un graphe d'appel statique pour python. De plus, il existe toutes sortes de méthodes d'importation de modules difficiles à analyser.

Je pense que votre meilleur pari sera de vous asseoir avec la base de code et un bloc de papier et de commencer à prendre des notes à la main. Cela aura le double avantage de vous familiariser avec la base de code et ne sera pas facilement trompé par des scénarios difficiles à analyser.

4
Wilduck