2010-08-26 17 views
13

Tengo un montón de módulos de Python que quiero limpiar, reorganizar y refactorizar (hay algún código duplicado, algún código no utilizado ...), y me pregunto si hay una herramienta para hacer un mapa de qué módulo usa qué otro módulo.Importar módulo de mapeo en Python para una fácil refactorización

Idealmente, me gustaría un mapa como este:

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 

... para que yo pudiera decir qué archivos que puedo comenzar a moverse primero (file_utils.py, db_access.py), qué archivos no son utilizados por mi main.py y pueden ser eliminados, etc. (en realidad estoy trabajando con alrededor de 60 módulos)

Escribir un script que hace esto probablemente no sería muy complicado (aunque hay diferentes sintaxis para importar manejar), pero también esperaría que no soy el primero en querer hacer esto (y si alguien hizo una herramienta para esto , podría incluir otras características interesantes como decirme qué clases y funciones probablemente no se usen).

¿Conoce alguna herramienta (incluso scripts simples) que ayude a la reorganización de código?

¿Conoces un término más exacto para lo que estoy tratando de hacer? Reorganización del código?

Respuesta

14

Python's modulefinder hace esto. Es bastante fácil escribir un script que convierta esta información en un gráfico de importación (que puede representar con, por ejemplo, graphviz): aquí hay un clear explanation. También hay snakefood el que hace todo el trabajo por usted (y el uso de los AST, también!)

Es posible que desee buscar en pylint o pychecker para tareas de mantenimiento más generales.

+1

No sabía de snakefood, muchas gracias por el enlace. +1 –

+1

¡Gracias! Logré obtener exactamente el mapa que estaba buscando robando descaradamente el código en la explicación que me enviaste y metiéndolo hasta que me dio el gráfico que necesitaba. También utilicé el buscador de módulos para enumerar los módulos que no estaba usando (más de la mitad), así que podría usar nukeem y no pensar más en ellos. También recibí una inyección, pero aún no jugué mucho. – Emile

4

Escribir un script que hace esto probablemente no sería muy complicado (aunque hay diferentes sintaxis para la importación de manejar),

es trivial. Hay import y from module import. Dos sintaxis para manejar.

¿Conoces un término más exacto para lo que estoy intentando hacer? Reorganización del código?

Diseño. Se llama diseño. Sí, estás refactorización un diseño ya existente, pero ...

Regla Uno

No inicie un esfuerzo de diseño con lo que tienes. Si lo hace, solo "mordisqueará los bordes" realizando cambios pequeños y a veces irrelevantes.

Regla Dos

Iniciar un esfuerzo de diseño con lo que debe haber tenido si sólo hubiera estado más inteligente. Piense de manera amplia y clara sobre lo que está realmente se supone que está haciendo. Ignora lo que hiciste

regla de tres

Diseño desde cero (o de novo como dicen algunas personas) con el paquete correcto y la arquitectura del módulo.

Cree un proyecto separado para esto.

Regla Cuatro

Primera prueba. Escribe pruebas unitarias para tu nueva arquitectura. Si tiene pruebas unitarias existentes, cópielas en el nuevo proyecto. Modifique las importaciones para reflejar la nueva arquitectura y vuelva a escribir las pruebas para expresar su gloriosa nueva simplificación.

Todas las pruebas fallan, porque no ha movido ningún código. Eso es bueno.

Regla Cinco

código Mover a la nueva estructura pasado. Deje de mover el código cuando pasen las pruebas.

No es necesario analizar las importaciones para hacer esto, por cierto. Solo está usando grep para encontrar módulos y clases. Las viejas importaciones y las relaciones enredadas entre las importaciones antiguas no importan, y no necesitan ser analizadas. Lo estás tirando. No necesita herramientas más inteligentes que grep.

Si siente un impulso de mover el código, debe ser muy disciplinado. (1) debe tener prueba (s) que fallan y luego (2) puede mover algún código para pasar la (s) prueba (s) fallida (s).

+1

+1. y no olvide 'import module.submod as submod' como variante. Ha estado creciendo en mí. – aaronasterling

+0

@aaronasterling: Todavía se ve como 'r" \ s * import \ s +. * "' Para mí. –

+0

Reescribir desde cero a menudo no es práctico y podría provocar el síndrome de Duke Nukem Forever. – Antimony

2

chuckmove es una herramienta que le permite volver a escribir de forma recursiva las importaciones en su árbol fuente completo para referirse a una nueva ubicación de un módulo.

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

... este desciende en src, y reescribe las declaraciones que importan sound.utils importar media.sound.utils lugar. Es compatible con toda la gama de formatos de importación de Python. Es decir. from x import y, import x.y.z as w etc.

Cuestiones relacionadas