2011-06-01 7 views
20

¿Es esta una buena práctica en Python (desde Active State Recipes -- Public Decorator)?¿Es una buena práctica agregar nombres a __all__ utilizando un decorador?

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 toma una función o una clase de y añade su nombre a la __all__ del módulo actual.

+2

Se arregló el título, como señalaron algunas personas –

+0

Si bien esto parece una buena idea, me parece que confunde mi IDE (PyCharm 2016.1.4), que en su mayoría frustra el propósito. Dado el soporte adecuado de IDE, lo usaría. –

+0

Obtener este decorador 100% a prueba de balas parece ser más difícil: vea el [error Python # 26632] (https://bugs.python.org/issue26632) y el módulo ['atpublic'] (https: // pypi. python.org/pypi/atpublic) mencionado allí. – kostix

Respuesta

6

Sí, es una buena práctica. Este decorador le permite expresar sus intenciones directamente en la definición de la función o la clase, en lugar de 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:helper sigue siendo accesible a un usuario del módulo de modulename.helper. Simplemente no se importa con from modulename import *.

+7

No necesariamente diría que es una buena práctica. La ventaja de tener un '__all__' explícitamente definido al comienzo de un módulo es que cualquiera (posiblemente usted) que lo mire puede determinar muy fácilmente qué se exporta a través de' import * 'y qué parte de la API pública del módulo. Usar un decorador público hace esto mucho más difícil. Sin embargo, si usa un decorador, puede decir mientras mira a un miembro del módulo si está en '__all__' o no. Entonces ambos tienen sus respectivos pros y contras. – darkfeline

+0

Todo lo que dice darkfeline plus: rompe intellisense/código completo en IDEs con tokenizadores de código ingenuos. – synthesizerpatel

1

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

+0

De forma automática, básicamente quería decir sin escribir el nombre explícitamente en la lista –

+1

Sí. (11 caracteres más para ir) – LaC

1

Creo que la pregunta es un poco subjetiva, pero me gusta la idea. Usualmente uso __all__ en mis módulos, pero a veces me olvido de agregar una nueva función que pretendía formar parte de la interfaz pública del módulo. Dado que 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 sintaxis comodín para importar toda la interfaz pública de un módulo) comienza a quejarse.

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

17

La forma más idiomática para hacer esto en Python es marcar los eventos privados como privada por comenzar su nombre con un guión bajo:

def public(x): 
     ... 


def _private_helper(y): 
    ... 

más personas estarán familiarizados con este estilo (que también es apoyado por el idioma: _private_helper no se exportará aunque no use __all__) que con su decorador public.

+2

Esto no parece resolver el problema que resuelve el decorador: mantener los nombres en '__all__' actualizados. –

+4

@EdL Esto se debe a que si usa caracteres de subrayado para las cosas "privadas" y no pone de relieve las cosas públicas, no necesitará '__all__' en absoluto –

+1

@TobiasKienzler ¿No se exportará ningún módulo importado? Probablemente aún quieras bloquearlos. –

Cuestiones relacionadas