Python 装饰器只是语法糖? [复制]

Posted

技术标签:

【中文标题】Python 装饰器只是语法糖? [复制]【英文标题】:Python decorators just syntactic sugar? [duplicate] 【发布时间】:2012-08-31 00:44:35 【问题描述】:

可能重复:Understanding Python decorators

我对使用 Python 装饰器还是很陌生,而且根据我的第一印象,它们只是语法糖。

对于更复杂的用途,它们是否有更深层次的用途?

【问题讨论】:

这里有使用示例的综合答案***.com/questions/739654/… 谢谢。真的很有用,我不知道如何关闭或删除此帖子。如果有人能做到这一点,那就太好了。 这里有一个小教程,您可以准确了解它们是什么:codementor.io/python/tutorial/introduction-to-decorators 不,语法糖的语法有限制。为了获得更高的灵活性,您可以在没有 @ 的情况下进行装饰 【参考方案1】:

是的,它是语法糖。没有它们,一切都可以实现,但需要多几行代码。但它可以帮助你编写更简洁的代码。

例子:

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

这是一个小样本,仅供参考。

【讨论】:

就此而言,所有编程语言结构都是语法糖。您始终可以直接在内存中写入要执行的指令。这种语法糖允许我们编写高级逻辑。 @Mahori 这显然是错误的。例如,defclass 构造不是语法糖。在编程语言的上下文中,语法糖有一个非常简洁的定义,请查阅。 @ratanplan 您是在暗示“语法糖”可以用于编程语言中可用的各种语言结构。我整体使用了“语法糖”,因此跨越了多种语言(就像原来的用法一样) - .请参阅此处的原始用法 - 语法糖一词是由 Peter J. Landin 在 1964 年创造的,用于描述一种简单的类似 ALGOL 的编程语言的表面语法,该语言是根据 lambda 演算的应用表达式在语义上定义的后来的编程语言,例如CLU、ML 和 Scheme,将该术语扩展为指一种语言中的语法 在提到“语法糖”时,我使用了其他所有人都表示的通用术语。有关更多信息,请查看当前的***条目。 我认为最初的问题是:装饰=语法糖。答案是不。你只是用@-notation 提供了很好的例子,并提到了它的优点。【参考方案2】:

我真的很喜欢装饰器语法,因为它让代码变得非常明确

例如,在 Django 中有这个 login_required 装饰器: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/

它已经失去了关于语言决策的历史,以及为什么

【讨论】:

以上是关于Python 装饰器只是语法糖? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

python-装饰器的最终形态和固定格式 语法糖

python:语法糖和装饰器

python学习day07 高阶函数 装饰器 语法糖

python装饰器 语法糖

python 入坑路--装饰器(语法糖)--高高潮

python_装饰器_语法糖