Как использовать `__all__` в собственных модулях?

Используйте __all__ в модуле, чтобы явно указать список публичных имен (переменных, функций, классов), которые будут экспортироваться при импорте модуля с использованием from module import *. Если __all__ не определен, по умолчанию экспортируются все имена, не начинающиеся с подчеркивания (_). Определение __all__ улучшает читаемость кода и предотвращает случайный экспорт внутренних компонентов.

__all__ - это список строк, определяющий публичный интерфейс модуля. Он используется, когда из модуля делается импорт с использованием from module import *. Если __all__ определен, то при такой форме импорта будут импортированы только имена, перечисленные в этом списке.

Зачем использовать __all__?

  • Явное указание публичного API: Помогает разработчикам явно указать, какие имена (функции, классы, переменные и т.д.) предназначены для использования пользователями модуля. Остальные имена считаются внутренними и не должны использоваться напрямую.
  • Предотвращение непреднамеренного импорта: Защищает от случайного импорта внутренних функций и классов, которые не должны быть частью публичного API.
  • Упрощение рефакторинга: Позволяет изменять внутреннюю структуру модуля без риска сломать код, использующий его, пока публичный API, определенный в __all__, остается неизменным.
  • Улучшение читаемости и поддержки: Облегчает понимание того, какие части модуля предназначены для внешнего использования.

Как использовать __all__:

  1. Определите __all__ в начале модуля: В начале файла модуля присвойте переменной __all__ список строк, содержащий имена, которые вы хотите сделать публичными.
  2. Укажите только имена: Список __all__ должен содержать только строки, представляющие имена функций, классов, переменных и т.д., которые вы хотите экспортировать.

Пример:


  # my_module.py

  __all__ = ['public_function', 'MyPublicClass']

  def public_function(x):
      """Эта функция является частью публичного API."""
      return x * 2

  class MyPublicClass:
      """Этот класс является частью публичного API."""
      def __init__(self, value):
          self.value = value

  def _private_function():  # Функция с префиксом "_" - обычно считается приватной
      """Эта функция не должна быть частью публичного API."""
      pass

  MY_PUBLIC_CONSTANT = 10

  

Использование:


  # main.py

  from my_module import *

  print(public_function(5))   # Работает
  my_object = MyPublicClass(20)  # Работает
  print(MY_PUBLIC_CONSTANT) # Будет работать, т.к. не был указан в __all__

  # _private_function() # Вызовет NameError, так как '_private_function' не была экспортирована.
  

Важно:

  • Если __all__ не определен, то при from module import * будут импортированы все имена, которые не начинаются с символа подчеркивания (_).
  • Если модуль использует __all__, то импортируются только те имена, которые явно указаны в этом списке, даже если другие имена не начинаются с _.
  • Переменная `__all__` должна быть списком строк.

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

0