2008-12-04 130 views
5

举个例子,Python装饰器在它装饰的函数被调用之前运行?

def get_booking(f=None): 
    print "Calling get_booking Decorator" 
    def wrapper(request, **kwargs): 
     booking = _get_booking_from_session(request) 
     if booking == None: 
      # we don't have a booking in our session. 
      return HttpRedirect('/') 
     else: 
      return f(request=request, booking=booking, **kwargs) 
    return wrapper 

@get_booking 
def do_stuff(request, booking): 
    # do stuff here 

我遇到的问题是,在@get_booking装饰正在我之前也叫,我装饰功能调用。

输出的开始:

Calling get_booking Decorator 
Calling get_booking Decorator 
Calling get_booking Decorator 
Calling get_booking Decorator 
Calling get_booking Decorator 
Calling get_booking Decorator 
Calling get_booking Decorator 
Calling get_booking Decorator 
Calling get_booking Decorator 
Calling get_booking Decorator 
[26/Oct/2008 19:54:04] "GET /onlinebooking/?id=1,2 HTTP/1.1" 302 0 
[26/Oct/2008 19:54:05] "GET /onlinebooking/ HTTP/1.1" 200 2300 
[26/Oct/2008 19:54:05] "GET /site-media/css/style.css HTTP/1.1" 200 800 
[26/Oct/2008 19:54:05] "GET /site-media/css/jquery-ui-themeroller.css HTTP/1.1" 200 25492 

我还没有还送被装饰在这一点上的函数的调用。

我刚刚开始与装饰,所以也许我失去了一些东西。任何帮助?

+0

要直接回答问题标题,请在装饰函数**之前运行装饰器。不,它在声明函数时不运行。它在函数为_called_时运行。我希望这有帮助。 – Jess 2016-10-27 14:50:35

回答

25

我相信python装饰器只是语法糖。

@foo 
def bar(): 
    pass 

是一回事

def bar(): 
    pass 
bar = foo(bar) 

正如你所看到的,被称为即使酒吧尚未调用。这就是你看到装饰器函数的输出的原因。你的输出应该包含你为装饰器应用的每个函数的一行。

0

一旦装饰函数被定义,就会调用装饰器。它等同于写这样的事情:

def __do_stuff(...): 
    ... 

do_stuff = get_booking(__do_stuff) 
0

蟒蛇装饰应用到函数的函数来转换它:

@my_decorator 
def function(): ... 

就像这样:

def function():... 
function = my_decorator(function) 

你想要什么要做的是:

def get_booking(f=None): 
    def wrapper(request, **kwargs): 
     print "Calling get_booking Decorator" 
     booking = _get_booking_from_session(request) 
     if booking == None: 
      # we don't have a booking in our session. 
      return HttpRedirect('/') 
     else: 
      return f(request=request, booking=booking, **kwargs) 
    return wrapper 
+0

给装饰器中的目标函数赋予默认值有什么好处? – muhuk 2008-12-04 22:31:40

2

由于您已经开始使用装饰器,因此我认为阅读这些内容会有所帮助,以便您事先知道陷阱和解决方法。

这里有两个链接,以前讨论装饰。

Python decorator makes function forget that it belongs to a class What does functools.wraps do?

而且,第二连杆提到“functools”的高阶函数的模块,其作用于或返回其它功能。建议使用functools.wraps,因为它保留了原始函数的文档字符串(装饰一)。

另一个问题是错误的方法签名,同时为我的项目生成自动文档。 但有一个解决方法: Preserving signatures of decorated functions

希望这会有所帮助。