2

我有以下示例代码,

def say_hello(f):
    def wrap():
        print "Hello"
    return wrap

def say_bye(f):
    def wrap():
        print "Bye"
    return wrap

@say_hello
@say_bye
def process():
    return "Processing"

process()

输出:

Hello

我期待输出为:

Bye
Hello
Processing
  1. 有什么问题?
  2. 如何制作将在函数调用之前和之后调用的装饰器?

意味着,上面的例子,我可以有输出:

    Hello
    Processing
    Bye 
4

3 回答 3

7

从装饰器返回的“包装”函数实际上并没有调用它们应该包装的函数。这是一个问题,因为从装饰器返回的函数在调用包装函数之前没有被调用;它替换了它包装的功能。以下装饰器语法:

@some_decorator
def func(arg):
    function_body()

是以下代码的语法糖:

def func(arg):
    function_body()
func = some_decorator(func)

因此,你想要的是

def say_hello(f):
    def wrap(*args, **kwargs):
        print "Hello"
        return f(*args, **kwargs)
    return wrap

def say_bye(f):
    def wrap(*args, **kwargs):
        return_value = f(*args, **kwargs)
        print "Bye"
        return return_value
    return wrap

@say_hello
@say_bye
def process():
    return "Processing"

这将产生

Hello
Processing
Bye
于 2013-09-06T05:04:53.123 回答
3

f()您应该在装饰器中调用该函数。现在要在第二个装饰器中打印值,在您的函数执行之后,您可以say_bye在打印之前在该装饰器 ( )中进行函数调用"Bye"

def say_hello(f):
    def wrap():
        print "Hello"
        f()          # call after printing
    return wrap

def say_bye(f):
    def wrap():
        f()          # call before printing
        print "Bye"
    return wrap

@say_hello
@say_bye
def process():
    print "Processing"

process()

输出:

Hello
Processing
Bye
于 2013-09-06T05:07:39.130 回答
0

您的代码与以下代码的工作方式相同:

fun = say_hello(say_bye(process))
fun()

其中 say_hello() 根本不使用它的参数。

于 2013-09-06T05:08:42.557 回答