首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Python装饰器和装饰器模式有什么区别?

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

Stack Overflow用户
提问于 2011-11-30 15:53:07
回答 2查看 9.6K关注 0票数 30

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

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

我正在寻找Python装饰器和完成相同功能的装饰器模式的示例。

@AcceptedAnswer

我知道雅各布·鲍耶的回答是有效的。然而,Srikar的回答让我明白了原因。

在Srikar的回答之后,并研究了给定的资源,我编写了这个示例,这样我就可以可视化和理解Python装饰器和装饰器模式。

我必须不同意Srikar的的"Python装饰器不是装饰器模式的实现“。在我了解了之后,我坚信Python是装饰器模式的一种实现。只是不是以经典的方式实现。

也是,我需要补充的是,尽管Srikar说“装饰器在定义时为函数和方法添加了功能”,但是可以很容易地在运行时中使用装饰器。

然而,我仍然认为Srikar的答案被接受了,因为它帮助我理解了Python中装饰模式的

代码语言:javascript
运行
复制
"""
Testing Python decorators against the 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 function
    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 the decorator pattern
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-11-30 15:56:21

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

Python中的--尽管名称如此,但装饰器并不是装饰器模式的实现。装饰器模式是静态类型化面向对象编程语言中使用的一种设计模式,允许在运行时将功能添加到对象中;Python装饰器在定义时向函数和方法添加功能,因此是一个比装饰-模式类更高级的构造。

装饰器模式本身在Python中是可以实现的,因为语言是鸭子类型的,因此通常不认为是这样的。因此,在Python中,修饰器是任何可调用的Python对象,用于修改函数、方法或类定义。

我希望我把区别说清楚了。以防万一你没有完全理解,请通过这些链接。你会在结束的时候表现得更清楚-

票数 36
EN

Stack Overflow用户

发布于 2017-05-08 22:58:14

不同之处在于:

(a) Python装饰器绑定到现有方法并更改该方法的行为。示例:

代码语言:javascript
运行
复制
@modifyBehavior
def original(myString):
    print myString

原作的行为被覆盖。您不能使用它来添加新功能。

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

代码语言:javascript
运行
复制
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

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8328824

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档