Является ли хорошей практикой добавлять имена в __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__
в своих модулях, но иногда забываю добавить новую функцию, которую я собирался быть частью открытого интерфейса модуля. Поскольку я обычно импортирую модули по имени, а не по подстановочным знакам, я не замечаю ошибку, пока кто-то из моей команды (который использует синтаксис подстановочных знаков для импорта всего публичного интерфейса модуля) начинает жаловаться.
Примечание: заголовок вопроса вводит в заблуждение, так как другие уже заметили среди ответов.