Предположим, у меня есть такая структура проекта
src
└── app
├── main.py
├── db
│ └── database.py
├── models
│ ├── model_a.py
│ └── model_b.py
└── tests
├── test_x.py
└── test_y.py
Я хочу проверить, какой файл использует класс или функцию из другого файла. У меня есть класс под названием Test в main.py
class Test:
pass
Я использовал этот класс в model_a
,
from ..main import Test
Но в model_b
я использовал
from ..main import Test
from ..db.database import Data
Я хочу проверить, какой файл использует другой файл, как и команда tree
, достаточно просто имени папки, поэтому я попробовал старый метод, но он был неэффективным, грязным, и я не ожидал этого. Метод заключался в том, что я создал файл в src
с именем check.py
, я импортировал все пакеты
from app.db import database
from app.models import model_a, model_b
from app.tests import test_x, test_y
from app import main
print('__file__={0:<35} | __name__={1:<20} | __package__={2:<20}'.format(__file__,__name__,str(__package__)))
И я добавил эту строку в конец всех файлов
print('__file__={0:<35} | __name__={1:<20} | __package__={2:<20}'.format(__file__,__name__,str(__package__)))
Итак когда я запускаю check.py
, я получаю этот результат
__file__=/home/yagiz/Desktop/struct/src/app/main.py | __name__=app.main | __package__=app
__file__=/home/yagiz/Desktop/struct/src/app/db/database.py | __name__=app.db.database | __package__=app.db
__file__=/home/yagiz/Desktop/struct/src/app/models/model_a.py | __name__=app.models.model_a | __package__=app.models
__file__=/home/yagiz/Desktop/struct/src/app/models/model_b.py | __name__=app.models.model_b | __package__=app.models
__file__=/home/yagiz/Desktop/struct/src/app/tests/test_x.py | __name__=app.tests.test_x | __package__=app.tests
__file__=/home/yagiz/Desktop/struct/src/app/tests/test_y.py | __name__=app.tests.test_y | __package__=app.tests
__file__=/home/yagiz/Desktop/struct/src/check.py | __name__=__main__ | __package__=None
Результат грязный и не соответствует моим ожиданиям. Есть ли способ получить такой результат?
main.py = app/models/model_a, app/models/model_b # These files imports something from main.py
models_b = None # No file imports from models_b
Обновление, я попробовал предложение @Hessam Korki это не работает .
Я просмотрел исходный код modulefinder и нашел его добавляет badmodule в каждый оператор импорта, который мне не нужен.
Вот как это произошло go, сначала я создал функцию, а также создал другую структуру проекта.
src
├── empty.py
├── __init__.py
├── main.py
├── module_finder.py
├── other
│ └── other.py
├── test
│ └── some_app.py
└── this_imports.py
Вот module_finder.py
, который содержит мою функцию
from modulefinder import ModuleFinder
file_names = ["this_imports.py", "main.py", "test/some_app.py", "other/other.py", "empty.py"]
def check_imports(file_names):
finder = ModuleFinder()
for file in file_names:
finder.run_script(file)
print("\n", file)
for name, mod in finder.modules.items():
print('%s: ' % name, end='')
print(','.join(list(mod.globalnames.keys())[:3]))
print('\n'.join(finder.badmodules.keys()))
Пустой файл пустой (как и ожидалось), в main.py
у меня есть
class Test:
pass
В this_imports.py
у меня только
from src.main import Test
В other/other.py
у меня
from src.main import Test
from src.test import DifferentTest
И для последнего в test/some_app.py
у меня
from src.main import Test
class DifferentTest:
pass
Так что ж Это должно быть:
empty.py = None
main.py = None
other/other.py = src.main , src.test
test/some_app.py = src.main
this_imports.py = src.main
Но функция дает неправильный результат, вот результат:
Filename: this_imports.py
__main__: Test
src.main
Filename: main.py
__main__: Test,__module__,__qualname__
src.main
Filename: test/some_app.py
__main__: Test,__module__,__qualname__
src.main
Filename: other/other.py
__main__: Test,__module__,__qualname__
src.main
src.test
Filename: empty.py
__main__: Test,__module__,__qualname__
src.main
src.test