Python Decorators run before function it is decorating is called?
举个例子,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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 decorator正在被调用,甚至在调用我正在装饰的函数之前。
启动时输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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 |
号
我甚至还没有调用在这一点上被修饰的函数。
我刚开始装修,所以可能我错过了一些东西。有什么帮助吗?
我相信python修饰器只是语法上的糖分。
1 2 3 | @foo def bar (): pass |
和
1 2 3 | def bar (): pass bar = foo(bar) |
号
正如你所看到的,即使酒吧还没有被调用,FOO也在被调用。这就是您看到decorator函数输出的原因。对于您应用了修饰符的每个函数,您的输出应该包含一行。
既然你是从装饰师开始的,我认为阅读这些会很有帮助,这样你就可以事先知道缺陷和解决方法。
这里有两个链接指向之前关于装饰师的讨论。
python decorator使函数忘记它属于一个类functools.wrapps做什么?
此外,第二个链接提到了"functools"模块,它是用于执行或返回其他函数的高阶函数。建议使用functools.wrapps,因为它保留了原始函数(修饰函数)的文档字符串。
另一个问题是为我的项目生成自动文档时方法签名错误。但有一个解决办法:保留修饰函数的签名
希望这有帮助。
python decorator是应用于函数以转换它的函数:
1 2 | @my_decorator def function (): ... |
。
就像这样:
1 2 | def function():... function = my_decorator(function) |
你想做的是:
1 2 3 4 5 6 7 8 9 10 | 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 |
。
一旦定义了修饰函数,就会调用decorator。它相当于写这样的东西:
1 2 3 4 | def __do_stuff(...): ... do_stuff = get_booking(__do_stuff) |