Импорт модулей сопоставления в Python для упрощения рефакторинга

У меня есть куча модулей Python, которые я хочу очистить, реорганизовать и реорганизовать (есть дублирующийся код, некоторый неиспользуемый код...), и мне интересно, есть ли инструмент для создания карты того, какой модуль использует какой другой модуль. .

В идеале мне нужна такая карта:

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

... чтобы я мог сказать, какие файлы я могу начать перемещать в первую очередь (file_utils.py, db_access.py), какие файлы не используются моим main.py и поэтому могут быть удалены и т. д. (я на самом деле работаю около 60 модулей)

Написание скрипта, который делает это, вероятно, не будет очень сложным (хотя существуют разные синтаксис для обработки импорта), но я также ожидаю, что я не первый, кто захочет сделать это (и если кто-то сделал инструмент для этого, он может включать другие полезные функции, такие как сообщение мне, какие классы и функции, вероятно, не используются).

Знаете ли вы какие-нибудь инструменты (даже простые скрипты), помогающие реорганизовать код?

Вы знаете более точный термин для того, что я пытаюсь сделать? Реорганизация кода?


person Emile    schedule 26.08.2010    source источник


Ответы (4)


Python modulefinder делает это. Довольно легко написать сценарий, который преобразует эту информацию в график импорта (который вы можете отобразить, например, с помощью graphviz): вот понятное объяснение. Также есть snakefood, который сделает всю работу за вас (и тоже использует AST!)

Вы можете изучить pylint или pychecker для более общих задач обслуживания.

person Katriel    schedule 26.08.2010
comment
Спасибо! Мне удалось получить именно ту карту, которую я искал, бесстыдно украв код в присланном вами объяснении и тыкая в него, пока он не дал мне нужный график. Я также использовал modulefinder, чтобы вывести список модулей, которые я не использовал (более половины), поэтому я мог просто уничтожить их и больше не думать о них. Я также получил pylint, но еще не играл с ним. - person Emile; 28.08.2010

Написание скрипта, который делает это, вероятно, не будет очень сложным (хотя есть разные синтаксис для обработки импорта),

Это тривиально. Есть import и from module import. Два синтаксиса для обработки.

Вы знаете более точный термин для того, что я пытаюсь сделать? Реорганизация кода?

Дизайн. Это называется дизайн. Да, вы рефакторите существующий дизайн, но...

Правило первое

Не начинайте работу над дизайном с тем, что у вас есть. Если вы это сделаете, вы будете только «кусать по краям», внося небольшие и иногда несущественные изменения.

Правило второе

Начните разработку с того, что должно было получить, если бы вы были умнее. Подумайте широко и ясно о том, что вы на самом деле должны делать. Не обращайте внимания на то, что вы сделали.

Правило третье

Проектируйте с нуля (или, как говорят некоторые, de novo) с правильной архитектурой пакетов и модулей.

Создайте для этого отдельный проект.

Правило четвертое

Сначала протестируйте. Напишите модульные тесты для вашей новой архитектуры. Если у вас есть существующие модульные тесты, скопируйте их в новый проект. Измените импорт, чтобы он отражал новую архитектуру, и перепишите тесты, чтобы выразить ваше великолепное новое упрощение.

Все тесты проваливаются, потому что вы не переместили код. Это хорошая вещь.

Правило пятое

Переместите код в новую структуру последним. Перестаньте перемещать код, когда тесты пройдены.

Вам не нужно анализировать импорт, чтобы сделать это, BTW. Вы просто используете grep для поиска модулей и классов. Старый импорт и запутанные отношения между старым импортом не имеют значения и не нуждаются в анализе. Вы выбрасываете это. Вам не нужны инструменты умнее, чем grep.

Если вы чувствуете желание переместить код, вы должны быть очень дисциплинированными. (1) у вас должны быть неудачные тесты, а затем (2) вы можете переместить некоторый код, чтобы пройти неудачный тест (ы).

person S.Lott    schedule 26.08.2010
comment
+1. и не забудьте import module.submod as submod как вариант. Это росло на мне. - person aaronasterling; 26.08.2010
comment
@aaronasterling: Мне все еще кажется r"\s*import\s+.*". - person S.Lott; 26.08.2010
comment
Переписывать с нуля часто нецелесообразно и может привести к синдрому Duke Nukem Forever. - person Antimony; 12.01.2013

chuckmove – это инструмент, который позволяет рекурсивно переписывать импорт во всем исходном дереве, чтобы ссылаться на новое местоположение модуль.

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

... это спускается в src и переписывает операторы, которые импортируют sound.utils, вместо этого импортируют media.sound.utils. Он поддерживает весь спектр форматов импорта Python. т.е. from x import y, import x.y.z as w и т. д.

person er0    schedule 14.01.2016

Modulefinder может не работать с Python 3.5*, но pydeps работал очень хорошо:

Установка:

sudo apt install python-pygraphviz
pip install pydeps

Затем в каталоге, из которого вы хотите сопоставить,

pydeps --max-bacon=0 .

..для создания карты максимальной глубины.

* Проблема в Python 3.5, но не в 3.6, вызвала проблемы с поиском модулей, аналогичные это

person cardamom    schedule 27.09.2018