2010-08-26 3 views
13

Ho un mucchio di moduli Python che voglio pulire, riorganizzare e refactare (c'è del codice duplicato, un po 'di codice inutilizzato ...), e mi chiedo se c'è uno strumento per creare una mappa di quale modulo utilizza quale altro modulo.Importazione del modulo di mappaggio in Python per un facile refactoring

Idealmente, mi piacerebbe una mappa come questa:

main.py 
-> task_runner.py 
    -> task_utils.py 
    -> deserialization.py 
    -> file_utils.py 
-> server.py 
    -> (deserialization.py) 
    -> db_access.py 

checkup_script.py 
re_test.py 
main_bkp0.py 
unit_tests.py 

... in modo da poter dire quali file posso iniziare a muoversi intorno prima (file_utils.py, db_access.py), quali file non sono utilizzati da mia main.py e così potrebbe essere cancellato, ecc (in realtà sto lavorando con circa 60 moduli)

Scrivi script che fa questo probabilmente non sarebbe molto complicato (anche se ci sono sintassi diverse per l'importazione da gestire), ma mi aspetto anche che non sia il primo a volerlo fare (e se qualcuno ha creato uno strumento per questo , potrebbe includere altre caratteristiche chiare come dirmi quali classi e funzioni non sono probabilmente usate).

Sei a conoscenza di alcuni strumenti (anche semplici script) che assistono la riorganizzazione del codice?

Conoscete un termine più preciso per ciò che sto cercando di fare? Riorganizzazione del codice?

risposta

14

Python's modulefinder esegue questa operazione. È abbastanza facile scrivere uno script che trasformerà queste informazioni in un grafico di importazione (che puoi eseguire il rendering con ad esempio graphviz): ecco uno clear explanation. C'è anche snakefood che fa tutto il lavoro per voi (e l'utilizzo di AST, anche!)

si potrebbe voler esaminare pylint o pychecker per le attività di manutenzione più generali.

+1

Non sapevo di snakefood, grazie mille per il collegamento. +1 –

+1

Grazie! Sono riuscito a ottenere esattamente la mappa che stavo cercando rubando senza vergogna il codice nella spiegazione che hai inviato e spaccandolo finché non mi ha dato il grafico di cui avevo bisogno. Ho anche usato il modulo per elencare i moduli che non stavo usando (più della metà), quindi potevo solo nuke'em e non pensarci più. Anch'io ho ricevuto un colpevole, ma non ci ho giocato ancora tanto. – Emile

4

Scrivi script che fa questo probabilmente non sarebbe molto complicato (anche se ci sono diverse sintassi per l'importazione da gestire),

è banale. C'è import e from module import. Due sintassi da gestire.

Conoscete un termine più preciso per ciò che sto cercando di fare? Riorganizzazione del codice?

Progettazione. Si chiama design. Sì, si sta refactoring un progetto esistente, ma ...

Regola Uno

Non avviare uno sforzo di progettazione con quello che hai. Se lo fai, ti basta "mordicchiare intorno ai bordi" apportando piccole e talvolta irrilevanti modifiche.

Regola Due

Avviare uno sforzo di progettazione con quello che si dovrebbe avere avuto se avessi solo sono stati più intelligenti. Pensa in modo ampio e chiaro a cosa stai facendo davvero. Ignora quello che hai fatto.

Regola Tre

design da zero (o de novo come dicono alcune persone) con il pacchetto corretto e l'architettura del modulo.

Creare un progetto separato per questo.

Regola Quattro

di prova. Scrivi test unitari per la tua nuova architettura. Se si dispone di test unitari esistenti, copiarli nel nuovo progetto. Modifica le importazioni per riflettere la nuova architettura e riscrivi i test per esprimere la tua gloriosa nuova semplificazione.

Tutti i test falliscono, perché non è stato spostato alcun codice. È una buona cosa.

Regola Cinque

codice Sposta nella nuova struttura ultima. Interrompe il trasferimento del codice quando i test passano.

Non è necessario analizzare le importazioni per fare ciò, a proposito. Stai solo utilizzando grep per trovare moduli e classi. Le vecchie importazioni e le relazioni intricate tra le vecchie importazioni non contano e non devono essere analizzate. Lo stai buttando via. Non hai bisogno di strumenti più intelligenti di grep.

Se senti il ​​bisogno di spostare il codice, devi essere molto disciplinato. (1) devi avere un test (s) che fallisce e poi (2) puoi spostare del codice per superare i test in errore.

+1

+1. e non dimenticare "import module.submod as submod' come una variante. Sta crescendo su di me. – aaronasterling

+0

@aaronasterling: sembra ancora 'r" \ s * import \ s +. * "' Per me. –

+0

Riscrivere da zero spesso non è pratico e potrebbe portare alla sindrome di Duke Nukem Forever. – Antimony

2

chuckmove è uno strumento che consente di riscrivere in modo ricorsivo le importazioni nell'intero albero dei sorgenti per fare riferimento a una nuova posizione di un modulo.

chuckmove --old sound.utils --new media.sound.utils src 

... questo scende in src, e riscrive le dichiarazioni che importano sound.utils importare media.sound.utils invece. Supporta l'intera gamma di formati di importazione Python. Cioè from x import y, import x.y.z as w ecc.