Python装饰器和装饰器模式有什么区别?

Python装饰器和装饰器模式有什么区别?

问题描述:

“Python装饰器”和“装饰器模式”有什么区别?Python装饰器和装饰器模式有什么区别?

什么时候应该使用Python装饰器,何时应该使用装饰器模式?

我正在寻找Python装饰器和装饰模式实现相同的例子吗?


@AcceptedAnswer
我知道Jakob Bowyer's answer是有效的。然而,Strikar的回答让我明白了原因。


在Srikar的回答和研究给出资源后,我写了这个例子,所以我可以看到和理解Python装饰器和装饰器模式。

我必须不同意与Strikar的“Python的装饰都没有装饰图案的实现”。在我学到的东西后,我坚信Python装饰器是Decorator模式的实现。只是没有经典的方式。

此外,我需要补充的是尽管Strikar说:“Python的装饰在定义时函数和方法添加功能” 你可以很容易地使用Pytohon装饰在运行时

但是,我仍然将Stiker的答案标记为已接受,因为它帮助我理解了装饰器模式的ImplementationPython

""" 
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是正确的。 [Here](http://stackoverflow.com/q/3118929/146792)的另一个SO问题,你可能会觉得有趣! – mac

+1

@Srikar,我不能接受Snswer,它不能解决Question中描述的问题,对不起,但是我的问题中提出的大多数解决方案都不起作用。 – seler

+0

@seler够公平的。 –

修饰器模式 - 在面向对象编程中,修饰器模式是一种设计模式,允许将行为动态添加到现有对象。装饰器模式可以用来在运行时扩展(修饰)某个对象的功能,而不依赖于同一类的其他实例,前提是在设计时进行一些基础工作。

Python中的装饰器 - 尽管有这个名称,Python装饰器并不是装饰器模式的实现。装饰器模式是静态类型的面向对象编程语言中使用的设计模式,允许在运行时将功能添加到对象; Python装饰器在定义时为函数和方法添加功能,因此是比装饰器模式类更高级别的构造。装饰器模式本身在Python中是可以实现的,因为语言是鸭子类型的,所以通常不会这样认为。所以在Python中,装饰器是用于修改函数,方法或类定义的可调用Python对象。

我希望我能明确区别。以防万一您完全不了解,请通过这些链接。你会出来比更清晰,在它的结束 -

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

你可能想看看编辑的问题。 – seler

python中的装饰器是装饰器设计中装饰器的应用。它们与人们在谈论语言实现以及设计和计算机科学概念的另一个方面是一回事。

+0

nope在这里看到http://wiki.python.org/moin/DecoratorPattern – Freelancer

所不同的是这样的:

(a)中的Python装饰被绑定到现有的方法和改变方法的行为。例如:

@modifyBehavior 
def original(myString): 
    print myString 

原件的行为被覆盖。您不能使用它来添加新功能。 (b)Decorator模式是关于多态性的。在上面的示例代码中,Decorator.something_useful的行为被覆盖。原来的方法丢失了。这不是真正的装饰模式。您应该期望增强或添加功能,而不是替换方法。您应该确保a.something_useful(string)返回与b.something_useful(string)相同的内容。实际上,在装饰模式中,您通常会替换原始对象。这里是我的意思:

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)) 

你可以有几个装饰添加功能。这允许您只在需要时添加所需的内容。更多阅读:GoF