real - Crear un gráfico de llamadas en python, incluidos los módulos y funciones?
matplotlib python (4)
En resumen, no existe tal herramienta. Python es un lenguaje demasiado dinámico para poder generar un gráfico de llamadas sin ejecutar el código.
Aquí hay un código que demuestra claramente algunas de las características muy dinámicas 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)
Tenga en cuenta que estamos utilizando eval
para crear una instancia de my_obj
y también usando getattr
para llamar a uno de sus métodos. Estos son ambos métodos que harían extremadamente difícil crear un gráfico de llamadas estáticas para Python. Además, hay todo tipo de formas difíciles de analizar para importar módulos.
Creo que lo mejor será sentarse con el código base y un bloc de notas, y comenzar a tomar notas a mano. Esto tendrá el doble beneficio de familiarizarte más con la base de códigos y no será fácilmente engañado por escenarios difíciles de analizar.
Tengo un montón de scripts para realizar una tarea. Y realmente necesito saber el gráfico de llamadas del proyecto porque es muy confuso. No puedo ejecutar el código porque necesita HW y SW extra para hacerlo. Sin embargo, necesito entender la lógica detrás de esto. Entonces, necesito saber si hay una herramienta (que no requiere la ejecución de un archivo python) que pueda construir un gráfico de llamadas usando los módulos en lugar del analizador de trazas o python. Tengo tales herramientas para C pero no para Python.
Gracias.
Es posible que desee comprobar pycallgraph:
También en este enlace se describe un enfoque más manual:
generating-call-graphs-for-understanding-and-refactoring-python-code
La mejor herramienta que he encontrado se llama pyan
, y fue escrita originalmente por Edmund Horner , mejorada por él y luego coloreada y otras características por Juha Jeronen . Esa versión tiene opciones útiles de línea de comandos:
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]
Este es el resultado de ejecutar pyan.py --dot -c -e pyan.py | fdp -Tpng
pyan.py --dot -c -e pyan.py | fdp -Tpng
:
El código original de Edmund Horner ahora se encuentra mejor en su repositorio github , y alguien también ha creado un repositorio con ambas versiones , desde donde puede descargar la versión de Juha Jeronen . He hecho una versión limpia que combina sus contribuciones en mi propio repositorio solo para pyan , ya que ambos repositorios tienen muchos otros programas.
No existe tal herramienta para ningún programa en ningún idioma. Crear una herramienta de este tipo sería equivalente a resolver el problema de detención, que es indecidible. En pocas palabras, dado un programa arbitrario y su entrada no hay ningún algoritmo para determinar si el programa se detendrá o se ejecutará para siempre. Del mismo modo, no existe un algoritmo que pueda determinar si la función x llamará a la función y, o si se ejecutará una determinada línea de código, etc. Claramente, para ciertos programas, uno puede determinar estos comportamientos. Por ejemplo, un programa de 1 línea con una declaración de impresión ejecutará trivialmente una línea y saldrá. Pero los programas arbitrarios pueden ser arbitrariamente complejos, por lo que se puede probar que no existe ningún algoritmo para determinar estos comportamientos para un programa arbitrario. Lamentablemente, debe poder ejecutar el programa para resolver este problema.