Является ли хорошей практикой добавлять имена в __all__, используя декоратор?

Является ли это хорошей практикой в ​​Python (от Active State Recipes - Public Decorator)?

import sys

def public(f):
  """Use a decorator to avoid retyping function/class names.

  * Based on an idea by Duncan Booth:
  http://groups.google.com/group/comp.lang.python/msg/11cbb03e09611b8a
  * Improved via a suggestion by Dave Angel:
  http://groups.google.com/group/comp.lang.python/msg/3d400fb22d8a42e1
  """
  all = sys.modules[f.__module__].__dict__.setdefault('__all__', [])
  if f.__name__ not in all:  # Prevent duplicates if run from an IDE.
      all.append(f.__name__)
  return f

public(public)  # Emulate decorating ourself

Общая идея заключалась бы в определении декоратора, который принимает функцию или класс и добавляет свое имя к __all__ текущего модуля.

Ответ 1

Да, это хорошая практика. Этот декоратор позволяет вам заявить о своих намерениях прямо по определению функции или класса, а не непосредственно после этого. Это делает ваш код более читаемым.

@public 
def foo():
    pass 

@public 
class bar():
    pass

class helper(): # not part of the modules public interface! 
    pass

Примечание. helper по-прежнему доступен пользователю модуля modulename.helper. Он просто не импортируется с помощью from modulename import *.

Ответ 2

Более идиоматический способ сделать это в Python - отметить частные функции как частные, начав их имя с подчеркивания:

def public(x):
      ...


def _private_helper(y):
    ...

Больше людей будут знакомы с этим стилем (который также поддерживается языком: _private_helper не будет экспортироваться, даже если вы не используете __all__), чем с вашим декоратором public.

Ответ 3

Это не автоматически добавляет имена в __all__, это просто позволяет вам добавить функцию ко всем, украсив ее с помощью @public. Мне кажется приятной идеей.

Ответ 4

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

Примечание: заголовок вопроса вводит в заблуждение, так как другие уже заметили среди ответов.