¿Es una buena práctica agregar nombres a __all__ usando un decorador?

¿Es esta una buena práctica en Python (de 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 

La idea general sería definir un decorador que tome una función o clase y agregue su nombre al __all__ del módulo actual.

Sí, es una buena práctica. Este decorador le permite indicar sus intenciones en la definición de la función o clase, en lugar de hacerlo directamente después. Eso hace que tu código sea más legible.

 @public def foo(): pass @public class bar(): pass class helper(): # not part of the modules public interface! pass 

Nota: el usuario del módulo aún puede acceder al modulename.helper mediante modulename.helper . Simplemente no se importa con importación from modulename import * .

La forma más idiomática de hacer esto en Python es marcar las funciones privadas como privadas al comenzar su nombre con un guión bajo:

 def public(x): ... def _private_helper(y): ... 

Más personas estarán familiarizadas con este estilo (que también es compatible con el idioma: _private_helper no se exportará incluso si no usa __all__ ) que con su decorador public .

Creo que la pregunta es un poco subjetiva, pero me gusta la idea. Normalmente uso __all__ en mis módulos, pero a veces me olvido de agregar una nueva función que pretendía ser parte de la interfaz pública del módulo. Como generalmente importo módulos por nombre y no por comodines, no noto el error hasta que alguien más en mi equipo (que usa la syntax de comodines para importar la interfaz pública completa de un módulo) comienza a quejarse.

Nota: el título de la pregunta es engañoso, ya que otros ya se han dado cuenta entre las respuestas.

Esto no agrega automáticamente nombres a __all__ , simplemente le permite agregar una función a todos decorándolos con @public . Me parece una buena idea.