2011-11-30 25 views
21

¿Cuál es la diferencia entre "decoradores Python" y el "patrón decorador"?¿Cuál es la diferencia entre los decoradores de Python y el patrón de decorador?

¿Cuándo debería usar los decoradores de Python, y cuándo debería usar el patrón de decorador?

Estoy buscando ejemplos de decoradores Python y el patrón decorador logrando lo mismo?


@AcceptedAnswer
sé que Jakob Bowyer's answer es válido. Sin embargo, la respuesta de Strikar es la que me hizo comprender por qué.


Después de la respuesta de Srikar y estudiando los recursos que he dado, he escrito este ejemplo, para poder visualizar y comprender los decoradores de Python y el patrón decorador.

debo no están de acuerdo con de Strikar "decoradores Python no son una implementación del patrón decorador". Después de lo que he aprendido Estoy muy convencido de que los decoradores de Python son la implementación del Patrón Decorador. Simplemente no de la manera clásica.

también, tengo que añadir que a pesar del hecho de que Strikar dijo "decoradores pitón añaden funcionalidad a las funciones y los métodos en tiempo de definición" puede utilizar simplemente decoradores Pytohon en tiempo de ejecución.

Aún así, sigo marcando la respuesta de Stiker como aceptada, porque me ayudó a entender Implementationde Decorator Pattern en Python.

""" 
Testing Python decorators against Decorator Pattern 
""" 
def function(string): 
    return string 

def decorator(wrapped): 
    def wrap(string): 
     # assume that this is something useful 
     return wrapped(string.upper()) 
    return wrap 

def method_decorator(wrapped): 
    def wrap(instance, string): 
     # assume that this is something useful 
     return wrapped(instance, string.upper()) 
    return wrap 

@decorator 
def decorated_function(string): 
    print('! '.join(string.split(' '))) 

class Class(object): 
    def __init__(self): 
     pass 
    def something_useful(self, string): 
     return string 

class Decorator(object): 
    def __init__(self, wrapped): 
     self.wrapped = wrapped 
    def something_useful(self, string): 
     string = '! '.join(string.split(' ')) 
     return self.wrapped().something_useful(string) 

    @method_decorator 
    def decorated_and_useful(self,string): 
     return self.something_useful(string) 


if __name__ == '__main__': 
    string = 'Lorem ipsum dolor sit amet.' 
    print(function(string))     # plain functioon 
    print(decorator(function)(string))  # Python decorator at run time 
    print(decorated_function(string))  # Python decorator at definition time 
    a = Class() 
    print(a.something_useful(string))  # plain method 
    b = Decorator(Class) 
    print(b.something_useful(string))  # Decorator Pattern 
    print(b.decorated_and_useful(string)) # Python decorator decorated Decorator Pattern 
+1

@Srikar es correcto. [Aquí] (http://stackoverflow.com/q/3118929/146792) ¡hay otra pregunta ASÍ que te puede resultar interesante! – mac

+1

@Srikar, no puedo aceptar que Snswer no resuelva el problema descrito en la Pregunta, lo siento, pero la mayoría de las soluciones propuestas en mis preguntas no funcionan. – seler

+0

@seler es suficiente. –

Respuesta

24

Decorador Patrón - En la programación orientada a objetos, el patrón de decorador es un patrón de diseño que permite que el comportamiento se agregue dinámicamente a un objeto existente. El patrón de decorador se puede usar para extender (decorar) la funcionalidad de un determinado objeto en tiempo de ejecución, independientemente de otras instancias de la misma clase, siempre que se realicen algunos preparativos en tiempo de diseño.

Decoradores en Python - A pesar del nombre, los decoradores de Python no son una implementación del patrón de decorador. El patrón de decorador es un patrón de diseño utilizado en lenguajes de programación orientados a objetos de tipo estático para permitir que la funcionalidad se agregue a los objetos en tiempo de ejecución; Los decoradores de Python agregan funcionalidad a las funciones y métodos en el momento de la definición, y por lo tanto son una construcción de alto nivel que las clases de patrones de decorador. El patrón de decorador en sí mismo es trivialmente implementable en Python, porque el lenguaje está escrito en pato, por lo que generalmente no se considera como tal. En Python, un decorador es cualquier objeto de Python invocable que se utiliza para modificar una función, método o definición de clase.

Espero haber hecho la diferencia clara. En caso de que no lo haya entendido por completo, consulte estos enlaces.Que va a salir más que claro al final de la misma -

How to make a chain of function decorators?

Implementing the decorator pattern in Python

What is the difference between using decorators and extending a sub class by inheritance?

Python Class Decorator

PyWiki - Python Decorators - A detailed discourse

Python Decorators Made Easy

source1 & source2

+0

Es posible que desee consultar la pregunta editada. – seler

0

Los decoradores en python son la aplicación de decoradores en el diseño de decorador. Ambos son lo mismo que uno habla de la implementación del lenguaje y el otro de un concepto de diseño e informática.

+0

nope aquí http://wiki.python.org/moin/DecoratorPattern – Freelancer

1

La diferencia es la siguiente:

(a) decoradores de Python están ligados a un método existente y cambiar el comportamiento de ese método. Ejemplo:

@modifyBehavior 
def original(myString): 
    print myString 

Se sobrescribe el comportamiento del original. No puede usar esto para agregar una nueva funcionalidad.

(b) El patrón del decorador es sobre polimorfismo. En el código de ejemplo anterior, se sobrescribe el comportamiento de Decorator.something_useful. El método original está perdido. No es realmente un patrón decorador. Debería buscar mejorar o agregar funcionalidad, no reemplazar un método. Debe asegurarse de que a.something_useful (cadena) devuelva lo mismo que b.something_useful (cadena). De hecho, en el patrón de decorador normalmente reemplazará el objeto original. Esto es lo que quiero decir:

class Class(object): 
    def __init__(self): 
     pass 
    def something_useful(self, string): 
     return string 

class Decorator(object): 
    def __init__(self, wrapped): 
     self._wrapped = wrapped 
    def withUnderscores(self, string): 
     return '_'.join(string.split(' ')) 
    def __getattr__(self, name): 
     return getattr(self._wrapped, name) 


if __name__ == '__main__': 
    string = 'Lorem ipsum dolor sit amet.' 
    obj = Class() 
    print('Original: ', obj.something_useful(string)) 
    #This has no underscore function. Use decorator to add. 
    obj = Decorator(obj) 
    print('Replaced spaces: ', obj.withUnderscores(string)) 
    print('Original still works: ', obj.something_useful(string)) 

puede tener varios decoradores para añadir funcionalidad. Esto le permite agregar solo lo que necesita cuando lo necesita. Más lectura: GoF

Cuestiones relacionadas