В чем разница между Python-декораторами и шаблоном декоратора? - PullRequest
21 голосов
/ 30 ноября 2011

В чем разница между «Python decorators» и «шаблоном декоратора»?

Когда я должен использовать декораторы Python и когда я должен использовать шаблон декоратора?

Я ищу примеры декораторов Python и шаблонов декораторов, выполняющих то же самое.

@ AcceptedAnswer

Я знаю, что Ответ Якоба Бойера действителен. И все же именно ответ Срикара заставил меня понять, почему.

После ответа Срикара и изучения данных ресурсов я написал этот пример, чтобы я мог визуализировать и понимать декораторы Python и шаблон декоратора.

Я должен не согласиться со словами Срикара " Python-декораторы не являются реализацией шаблона декоратора ". После того, что я узнал, Я твердо убежден, что декораторы Python являются реализацией шаблона декоратора. Просто не в классическом смысле.

Также , мне нужно добавить, что, несмотря на то, что Срикар сказал « Python-декораторы добавляют функциональность к функциям и методам во время определения », вы можете легко использовать Python декораторы во время выполнения .

Тем не менее, я все еще отмечаю ответ Срикара как принятый, потому что он помог мне понять реализацию шаблона декоратора в Python .

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

Ответы [ 3 ]

25 голосов
/ 30 ноября 2011

Шаблон декоратора - В объектно-ориентированном программировании шаблон декоратора является шаблоном проектирования, который позволяет динамически добавлять поведение к существующему объекту. Шаблон декоратора может использоваться для расширения (декорирования) функциональности определенного объекта во время выполнения, независимо от других экземпляров того же класса, при условии, что во время разработки сделаны некоторые фундаментальные работы.

Декораторы в Python - Несмотря на название, декораторы Python не являются реализацией шаблона декоратора. Шаблон декоратора - это шаблон проектирования, используемый в статически типизированных объектно-ориентированных языках программирования, чтобы позволить функциональность быть добавленной к объектам во время выполнения; Декораторы Python добавляют функциональность к функциям и методам во время определения и, таким образом, представляют собой конструкцию более высокого уровня, чем классы шаблонов декораторов.

Сам шаблон декоратора тривиально реализуем в Python, потому что язык написан по типу утки, и поэтому обычно не рассматривается как таковой. Поэтому в Python декоратором является любой вызываемый объект Python, который используется для изменения определения функции, метода или класса.

Надеюсь, я понял разницу. Если вы не совсем поняли, перейдите по этим ссылкам. Вы выйдете более чем ясно в конце этого -

1 голос
/ 09 мая 2017

Разница заключается в следующем:

(a) Декораторы Python привязаны к существующему методу и изменяют поведение этого метода.Пример:

@modifyBehavior
def original(myString):
    print myString

Поведение оригинала перезаписывается.Вы не можете использовать это, чтобы добавить новую функциональность.

(b) Шаблон декоратора о полиморфизме.В приведенном выше примере кода поведение 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

0 голосов
/ 30 ноября 2011

Декораторы в Python - это применение декораторов в дизайне декораторов.

Они оба одно и то же. Один говорит о реализации языка, а другой - о концепции дизайна и информатики.

...