Подтвердить что ты не робот

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

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

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

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

@AcceptedAnswer

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

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

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

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

Тем не менее, я по-прежнему отмечаю ответ Srikar как принятый, потому что он помог мне понять реализацию шаблона декоратора в 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
4b9b3361

Ответ 1

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

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

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

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

Ответ 2

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

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

@modifyBehavior
def original(myString):
    print myString

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

(b) Рисунок декоратора о полиморфизме. В приведенном выше примере кода поведение Decorator.something_useful перезаписывается. Исходный метод потерян. Это не образец декоратора. Вы должны искать улучшения или добавления функциональности, а не заменять метод. Вы должны убедиться, что a.something_useful (string) возвращает ту же вещь, что и b.something_useful (строка). Фактически, в шаблоне декоратора вы обычно заменяете оригинальный объект. Вот что я имею в виду:

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

У вас может быть несколько декораторов, чтобы добавить функциональность. Это позволяет вам добавлять только то, что вам нужно, когда вам это нужно. More reading: GoF

Ответ 3

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

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