Disegna un grafico di chiamata

Sto mantenendo una vecchia base di codice scritta in python. In particolare cè una parte di codice complessa che da un modulo chiama altre funzioni da altri moduli che chiamano altre funzioni e così via. Non è OOP, solo funzioni e moduli.
Ho provato a tenere traccia di dove inizia e finisce il flusso ogni volta che chiamo la funzione principale ma sento di aver bisogno di disegnare questo perché mi sto perdendo nelle chiamate secondarie.

Ciò che mi preoccupa è che ogni funzione chiama più funzioni esterne allinterno del proprio corpo per completare il loro compito e restituire il valore al chiamante.

Come posso disegnarlo? Significa che tipo di grafico / grafico sarebbe appropriato per documentare questo tipo di comportamento / codice?

Quindi, non penso sarebbe utile disegnare un diagramma UML , né un diagramma di flusso. Un grafico delle chiamate, forse?

Commenti

  • doxygen – genererà grafici delle chiamate / dei chiamanti, I ' Non sono sicuro di quanto supporto abbia per Python. So che puoi documentare il codice Python per questo.
  • ' ho provato pycallgraph ma ' è semplicemente troppo complicato / troppo profondo per usarlo. Ciò è dovuto alla complessità del mio codice perché mescola Python semplice con django e chiamata esterna allURL dellAPI. Ecco perché ho voluto disegnarlo a mano tenendo conto solo della parte rilevante di cui avevo bisogno. Il problema è che io non ' non so che tipo di grafico usare per avere una piena comprensione del sistema
  • Se questo è solo per aiutarti a capirlo , disegna semplicemente quello che ti viene naturale. Puoi sempre riordinarlo in un secondo momento se ' sta entrando nella documentazione formale.

Rispondi

Penso che quello che stai cercando qui sia un diagramma di sequenza . Questi ti consentono di visualizzare lordine in cui i vari moduli chiamano lun laltro tramite luso delle frecce.

Costruirne uno è semplice:

  1. Disegna la tua classe di partenza con una linea tratteggiata sotto di essa.
  2. Disegna la prossima classe / metodo nella traccia delle chiamate con una linea tratteggiata sotto
  3. Collega le linee con una freccia, posizionata verticalmente sotto lultima freccia che hai disegnato
  4. Ripeti i passaggi 2-3 per tutte le chiamate nella tua traccia

Esempio

Supponiamo di avere il seguente codice per cui vogliamo creare un diagramma di sequenza:

def long_division(quotient, divisor): solution = "" remainder = quotient working = "" while len(remainder) > 0: working += remainder[0] remainder = remainder[1:] multiplier = find_largest_fit(working, divisor) solution += multiplier working = calculate_remainder(working, multiplier, divisor) print solution def calculate_remainder(working, multiplier, divisor): cur_len = len(working) int_rem = int(working) - (int(multiplier) * int (divisor)) return "%*d" % (cur_len, int_rem) def find_largest_fit(quotient, divisor): if int(divisor) == 0: return "0" i = 0 while i <= 10: if (int(divisor) * i) > int(quotient): return str(i - 1) else: i += 1 if __name__ == "__main__": long_division("645", "5") 

La prima cosa che disegneremo è il punto di ingresso (main) che si collega al metodo long_division . Nota che questo crea una scatola in long_ divisione, che indica lambito della chiamata al metodo. Per questo semplice esempio, la casella sarà lintera altezza del nostro diagramma di sequenza perché questa è lunica cosa eseguita.

inserisci qui la descrizione dellimmagine

Ora chiamiamo find_largest_fit per trovare il multiplo più grande che rientra nel nostro numero di lavoro e ce lo restituisce. Tracciamo una linea da long_division a find_largest_fit con unaltra casella per indicare lambito della chiamata di funzione. Nota come la casella finisce quando viene restituito il moltiplicatore; questa è la fine dellambito delle funzioni!

inserisci qui la descrizione dellimmagine

Ripeti alcune volte per un numero più grande e il tuo grafico dovrebbe assomigliare a questo:

invio descrizione dellimmagine qui

Note

Puoi scegliere se etichettare le chiamate con i nomi delle variabili passati, o i loro valori se lo desideri solo documentare un caso specifico. Puoi anche mostrare la ricorsione con una funzione che chiama se stessa.

Inoltre, puoi mostrare gli utenti qui e chiedere loro e mostrare il loro input nel sistema abbastanza facilmente. È “un sistema abbastanza flessibile che penso troverai piuttosto utile!

Commenti

  • Grazie, conosco il diagramma di sequenza, ma mi sembra che sia più adatto per oop. Nel mio caso le cose sono un po più disordinate, il che significa che ad esempio ho circa 20 funzioni / helper distribuiti su più moduli. Come dovrei specificare il modulo a cui appartiene la funzione? Considerando che alcune funzioni vengono rinominate anche durante le importazioni ..
  • Direi che non importa quanti moduli hai – lesempio sopra non lo è affatto. Basta nominarli in modo da poterli trovare in seguito, ModuleA / function1, ModuleB / Function2 ecc. Per 20 funzioni sarà più grande, ma sicuramente non impossibile da capire. Unaltra cosa che puoi fare è terminare la riga di una funzione dopo il suo ultimo utilizzo e inserire unaltra riga di funzioni sotto di essa per risparmiare spazio orizzontale nel diagramma.

Rispondi

Penso che un grafico di chiamata sarebbe la visualizzazione più appropriata.Se decidi di non farlo a mano, esiste un “piccolo strumento carino chiamato pyan che esegue analisi statiche su un file python e può generare un grafico delle chiamate visualizzato tramite un punto grafico file (che può essere sottoposto a rendering in unimmagine). Ci sono stati un paio di fork, ma il più completo sembra essere https://github.com/davidfraser/pyan .

Devi solo specificare tutti i file che desideri vengano elaborati quando esegui il comando:

python ~/bin/pyan.py --dot a.py b.py c.py -n > pyan.dot; dot -Tpng -opyan.png pyan.dot

o

python ~/bin/pyan.py --dot $(find . -name "*.py") -n > pyan.dot; dot -Tpng -opyan.png pyan.dot

Puoi rendere il grafico più pulito con “-n” che rimuove il linee che mostrano dove è stata definita una funzione.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *