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

可能重复:
Understanding Python decorators

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

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

【问题讨论】:

标签: python decorator syntactic-sugar


【解决方案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/

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-16
    • 1970-01-01
    • 2011-03-09
    • 1970-01-01
    • 2022-11-29
    • 2020-11-07
    • 2012-02-09
    • 2020-07-24
    相关资源
    最近更新 更多