Декораторы Python просто синтаксический сахар?

Возможный дубликат:
Общие сведения о декораторах Python

Я новичок в использовании декораторов Python и, насколько я понимаю по моему первому впечатлению, это всего лишь синтаксический сахар.

Есть ли их более глубокое применение для более сложных задач?


person coredump    schedule 06.09.2012    source источник
comment
Здесь есть исчерпывающий ответ с примерами использования stackoverflow.com/ questions / 739654 /   -  person Hedde van der Heide    schedule 06.09.2012
comment
Спасибо. Это действительно полезно. Я не знаю, как закрыть или удалить этот пост. Если бы кто-то мог это сделать, было бы здорово.   -  person coredump    schedule 06.09.2012
comment
А вот небольшой учебник, чтобы вы могли точно увидеть, что это такое: codementor.io / python / tutorial / Introduction-to-decorators   -  person Sheena    schedule 25.03.2015


Ответы (2)


Да, это синтаксический сахар. Все можно сделать и без них, но с помощью еще нескольких строк кода. Но это помогает писать более лаконичный код.

Примеры:

from functools import wraps

def requires_foo(func):
    @wraps(func)
    def wrapped(self, *args, **kwargs):
        if not hasattr(self, 'foo') or not self.foo is True:
            raise Exception('You must have foo and be True!!')
        return func(self, *args, **kwargs)
    return wrapped

def requires_bar(func):
    @wraps(func)
    def wrapped(self, *args, **kwargs):
        if not hasattr(self, 'bar') or not self.bar is True:
            raise Exception('You must have bar and be True!!')
        return func(self, *args, **kwargs)
    return wrapped

class FooBar(object):

    @requires_foo                 # Make sure the requirement is met.
    def do_something_to_foo(self):
        pass

Мы также можем связать / сложить декораторы друг на друга.

class FooBar(object):
    @requires_bar
    @requires_foo                 # You can chain as many decorators as you want
    def do_something_to_foo_and_bar(self):
        pass

Хорошо, у нас может получиться множество декораторов друг над другом.

Я знаю! Я напишу декоратор, который применяет другие декораторы.

Итак, мы могли сделать это:

def enforce(requirements):
    def wrapper(func):
        @wraps(func)
        def wrapped(self, *args, **kwargs):
            return func(self, *args, **kwargs)
        while requirements:
            func = requirements.pop()(func)
        return wrapped
    return wrapper

class FooBar(object):
    @enforce([reguires_foo, requires_bar])
    def do_something_to_foo_and_bar(self):
        pass

Это небольшой образец, с которым можно поиграться.

person rantanplan    schedule 06.09.2012
comment
В этом отношении все конструкции языка программирования - это синтаксический сахар. Вы всегда можете напрямую записать инструкции в память для выполнения. Этот синтаксический сахар позволяет нам писать логику высокого уровня. - person Mahori; 30.01.2020
comment
@Mahori, это явно неправда. Например, конструкции def и class не являются синтаксическим сахаром. Есть довольно краткое определение синтаксического сахара в контексте языков программирования, поищите его. - person rantanplan; 30.01.2020
comment
@ratanplan Вы имеете в виду, что синтаксический сахар может использоваться в терминах различных языковых конструкций, доступных в языке программирования. Я использую синтетический сахар как единое целое, таким образом, охватывая несколько языков (как и в оригинале) -. См. Исходное использование здесь. Термин «синтаксический сахар» был придуман Питером Дж. Ландином в 1964 году для описания поверхностного синтаксиса простого АЛГОЛ-подобного языка программирования, который был определен семантически в терминах прикладных выражений лямбда-исчисления. Более поздние языки программирования, такие как CLU, ML и Scheme расширили термин, чтобы обозначить синтаксис в языке. - person Mahori; 30.01.2020
comment
Я использовал общий термин, который имеют в виду все остальные, говоря о синтаксическом сахаре. Для получения дополнительной информации проверьте текущую запись в Википедии. - person rantanplan; 31.01.2020

Мне очень нравится синтаксис декоратора, потому что он делает код более явным

Например, в Django есть декоратор, требующий входа в систему: https://docs.djangoproject.com/en/dev/topics/auth/#django.contrib.auth.decorators.login_required

Чтобы ввести поведение @login_required для функции / представления, все, что вам нужно сделать, это прикрепить к нему декоратор (в отличие от размещения if: ... else: ... управляющих выражений повсюду и т. Д.)

Прочтите PEP!

http://www.python.org/dev/peps/pep-0318/

он потерял историю о языковых решениях, которые были приняты, и почему

person David Lam    schedule 06.09.2012