在调用它所修饰的函数之前运行修饰程序?

2024-05-29 11:21:28 发布

您现在位置: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 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
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

我甚至还没有调用在这一点上被修饰的函数

我刚开始接触装饰师,所以可能我遗漏了一些东西


Tags: nonehttpgetreturnrequestsessiondefdecorator
3条回答

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

@foo
def bar ():
    pass

是同一件事吗

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

如您所见,foo正在被调用,即使bar尚未被调用。这就是为什么您会看到decorator函数的输出。您的输出应该为应用装饰器的每个函数包含一行

由于您是从装饰师开始的,我认为阅读这些内容会很有帮助,这样您就可以事先了解缺陷和解决方法

这里有两个链接可以链接到之前关于装饰器的讨论

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

此外,第二个链接提到“functools”,这是一个用于高阶函数的模块,作用于或返回其他函数。建议使用functools.wrapps,因为它保留原始函数(修饰函数)的文档字符串

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

希望这有帮助

一旦定义了修饰函数,就会调用修饰器。这相当于写这样的东西:

def __do_stuff(...):
    ...

do_stuff = get_booking(__do_stuff)

相关问题 更多 >

    热门问题