了解这两种装饰器的区别

Posted

技术标签:

【中文标题】了解这两种装饰器的区别【英文标题】:Understanding the difference between these two decorators 【发布时间】:2016-03-12 21:32:41 【问题描述】:

Python 新手并试图理解这两个装饰器之间的区别,其中装饰器 A 将其装饰的函数作为其参数,而装饰器 B 似乎将装饰函数传递给其自身内部的函数。

装饰A:

def my_decorator(some_function):

  def wrapper():

      print "Something is happening before some_function() is called."

      some_function()

      print "Something is happening after some_function() is called."

  return wrapper

@ my_decorator
def just_some_function():
  print "Wheee!"

将产生:

Something is happening before some_function() is called.
Wheee!
Something is happening after some_function() is called.
None

装饰者乙:

def decorator_factory(enter_message, exit_message):

    def simple_decorator(f):
        def wrapper():
            print enter_message
            f()
            print exit_message
        return wrapper
    return simple_decorator

@decorator_factory("Start", "End")
def hello():
    print "Hello World"

将产生:

Start
Hello World
End
None

我了解使用装饰器 A,some_function() 可以传递给 def wrapper(),因为 my_decorator()some_function 作为其参数。

但是对于装饰器 B,当 decorator_factory()"start""End" 作为其参数而不是 def hello() ? Python 如何“知道”看似自动将def hello() 传递给simple_decorator()

【问题讨论】:

@decorator_factory(...) 是一个函数调用。然后将该函数调用的结果应用于修饰函数;) 【参考方案1】:

所以没有人正确回答你的问题:你想知道装饰器 B simple_decorator 如何获得函数 f 这是因为 decorator_factory 返回 simple_decorator 函数所以:decorator_factory("Start", "End")(hello) 实际上等同于 @ 987654326@(你好是你的f

附:您可以在 cmets 中找到有关 2 组参数的问题的答案。

【讨论】:

【参考方案2】:

装饰器相当于包装它所装饰的函数。

你的例子

@decorator_factory("Start", "End")
def hello():
    print "Hello World"

hello()

一样
def hello():
    print "Hello World"

hello = decorator_factory("Start", "End")(hello)

hello()

【讨论】:

在 Python 中可以通过以下方式将两组参数传递给一个函数:decorator_factory("Start", "End")(hello()) ? @Malvin9000 这些不是同一个函数的 2 个单独的参数集,而是 2 个不同的函数:第一组 ("Start", "End") 被传递给 decorator_factory,它返回一个以 (hello) 为参数的函数它的论点。【参考方案3】:

装饰器A

@ my_decorator
def just_some_function():

等于:

just_some_function = my_decorator(just_some_function)

装饰器 B

@decorator_factory("Start", "End")
def hello():

等于

hello = decorator_factory("Start", "End")(hello)

因为它在使用前被调用一次,所以它更深了一步

【讨论】:

应该是def just_some_function() .... just_some_function = my_decorator(just_some_function)【参考方案4】:
@decorator
def foo():
    ...

只是语法糖

def foo():
    ...

foo = decorator(foo)

因此

@decorator_factory(...)
def hello():
    ...

等价于

def hello():
    ...

hello = decorator_factory(...)(hello)

当然等价于

def hello():
    ...

decorator = decorator_factory(...)
hello = decorator(hello)

【讨论】:

所以在 Python 中,可以有两个参数,将两个单独的参数传递给一个函数,例如 hello = decorator_factory(...)(hello) ? @Malvin9000 这些不是同一个函数的 2 个不同的参数集,而是 2 个不同的函数:第一组 (...) 被传递给 decorator_factory,它返回一个以 (hello) 为它的论点。 @Malvin9000:打个比方,让我们假设装饰器就像帽子。函数戴帽子。 decorator 是你戴在函数上的帽子。另一方面,decorator_factory 是一个制作帽子的函数。该函数的返回值是一个可以放在函数上的帽子。 @JoelCornett 好的,所以decorator_factory() 的返回值(返回/调用内部函数simpler_decorator())是hello() 的实际装饰器?

以上是关于了解这两种装饰器的区别的主要内容,如果未能解决你的问题,请参考以下文章

添加登录装饰器的两种方式:FBV和CBV

python装饰器了解

6.5装饰器的类型

React js - HPC 和装饰器有啥区别

Python——装饰器基础

python staticmethod,classmethod方法的使用和区别以及property装饰器的作用