What is the difference between Python decorators and the decorator pattern?

前端 未结 2 460
长发绾君心
长发绾君心 2020-12-12 21:20

What is the difference between “Python decorators” and the “decorator pattern”?

When should I use Python decorators, and when should I use the decorator pattern?

相关标签:
2条回答
  • 2020-12-12 21:38

    Decorator Pattern - In object-oriented programming, the decorator pattern is a design pattern that allows behaviour to be added to an existing object dynamically. The decorator pattern can be used to extend (decorate) the functionality of a certain object at run-time, independently of other instances of the same class, provided some groundwork is done at design time.

    Decorators in Python - Despite the name, Python decorators are not an implementation of the decorator pattern. The decorator pattern is a design pattern used in statically typed object-oriented programming languages to allow functionality to be added to objects at run time; Python decorators add functionality to functions and methods at definition time, and thus are a higher-level construct than decorator-pattern classes.

    The decorator pattern itself is trivially implementable in Python, because the language is duck typed, and so is not usually considered as such. So in Python a decorator is any callable Python object that is used to modify a function, method or class definition.

    I hope I made the difference clear. Just in case you did not completely understand, please go through these links. You will come out more than clear at the end of it -

    • 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

    • Source 1 & source 2

    0 讨论(0)
  • 2020-12-12 21:58

    The difference is this:

    (a) Python decorators are tied to an existing method and change the behavior of that method. Example:

    @modifyBehavior
    def original(myString):
        print myString
    

    The behavior of original is overwritten. You can't use this to add a new functionality.

    (b) Decorator pattern is about polymorphism. In your sample code above, the behavior of Decorator.something_useful is overwritten. The original method is lost. It's not really decorator pattern. You should be looking to enhance or add functionality, not replace a method. You should ensure that a.something_useful(string) returns the same thing as b.something_useful(string). In fact, in decorator pattern you would typically replace the original object. Here is what I mean:

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

    You can have several decorators to add functionality. This allows you to add only what you need when you need it. More reading: GoF

    0 讨论(0)
提交回复
热议问题