Разделить модуль Python без рефакторинга всех использований

#python #python-import

#python #python-импорт

Вопрос:

Предположим, у меня есть модуль python heavy_module.py, который определяет:

 from foo.bar import heavy_dependency

class A:
 ...

class B:
 ...

# etc
class HeavyClass:
 def init:
   self.x = heavy_dependency()

def top_level_foo(bar):
  ...

x = top_level_foo(some_value)
  

теперь в других файлах проекта у меня есть:

 from heavy_module import A, B
  

или

 from heavy_module import x, top_level_foo
  

или любая другая комбинация. Однако некоторые места импортируются HeavyClass . Моя цель — разделить heavy_module.py на 2 части, чтобы результирующие двоичные файлы были меньше: легкие классы и тяжелые классы (которые полагаются на heavy_dependency). Однако я не хочу изменять импорт классов / методов из heavy_module.

Есть ли способ внедрить light_module.py , импортировать его каким-то образом в heavy_module.py и сохранить весь внешний импорт таким, какой он есть?

Комментарии:

1. from heavy_module import A, B обработает весь модуль, даже если вы используете только A и B

2. @alani верно. Однако позже я могу пойти и изменить его на light_module import A, B файл за файлом, а не все сразу

3. Предоставьте свою структуру каталогов для хранения этих файлов.

Ответ №1:

Это довольно просто, вы можете просто создать light_module.py , переместить в него все, что хотите, и импортировать в heavy_module :

 # heavy_module.py
from light_module import A, B, x, y
  

Теперь вы можете from heavy_module import A или from light_module import A , и оба будут работать.


Если вы хотите быть немного более «структурированным» в своем разделении, вы также можете преобразовать heavy_module в пакет:

 src/
└── heavy_module/
    ├── __init__.py
    ├── heavy_stuff.py
    └── light_stuff.py
  

Затем вы можете импортировать все в __init__.py из обоих:

 # __init__.py
from heavy_stuff import X, Y, Z
from light_stuff import A, B, C
  

И для отдельных импортов вы могли бы сделать: from heavy_module.light_stuff import A

Комментарии:

1. конечно:) Есть ли способ импортировать все классы / методы из light_module без их перечисления?

2. из light_module import * будут импортированы все общедоступные объекты

3. @NikitaTook Вы можете сделать from light_module import * , и все общедоступные имена будут импортированы; просто обычно считается лучшей практикой указывать, что вы импортируете.