python flask route中裝飾器的使用

問題:route中的裝飾器爲何感受和平時使用的不太同樣,裝飾器帶參數和不太參數有什麼區別?被修飾的函數帶參數和不帶參數有什麼區別?python

測試1:裝飾器不帶參數,被修飾的函數也不帶參數。flask

def log(func):
    print"execute log"
    print func
    def use_log():
        print "execute use log"
        def wrapper():
            print "start"
            func()
            print "end"
            return
        return wrapper
    return use_log

@log
def cal():
    print "1+2"

此時輸出爲:app

execute log
<function cal at 0x7fa64535f668> #這裏的function爲cal的函數地址

若是執行cal()那麼將會使用use_log函數,返回的是wrapper()函數

execute log
<function cal at 0x7f42ee7a4668>
execute use log

若是執行cal()的返回值,那麼將執行cal()函數體的內容測試

result = cal()
result()

結果爲:this

execute log
<function cal at 0x7f38dc4d1668>
execute use log
start
1+2
end

測試2:若是裝飾器帶參數,被修飾的函數不帶參數url

def log(func): #這裏的func爲裝飾器函數參數
    print"execute log"
    print func #這裏的func爲裝飾器函數參數
    def use_log(func): #這裏的func爲函數cal()的地址
        print "execute use log"
        print func #這裏的func爲函數cal()的地址
        def wrapper():
            print "start"
            func()
            print "end"
            return
        return wrapper
    return use_log

@log('log')
def cal():
    print "1+2"

#這個時候數輸出結果爲:
execute log
log
execute use log
<function cal at 0x7f0c666b46e0>

 這個時候調用cal()那麼將會執行wrapper()的函數體+cal()的函數體。spa

測試3:若是裝飾器不帶參數,被修飾的函數帶參數code

def log(func): #func 爲cal()函數的地址
    print"execute log"
    def use_log(param): #param爲cal的參數param
        print "execute use log"
        print param
        def wrapper():
            print "start"
            func(param) #func 爲cal()函數的地址,param爲cal的參數param
            print "end"
            return
        return wrapper
    return use_log

@log
def cal(param):
    print "1+2"

result = cal('cal')
result()

#執行的結果爲:
execute log
execute use log
cal
start
1+2
end
#若是注掉最後兩行代碼,那麼只有輸出
execute log

 測試4:若是裝飾器帶參數,被修飾的函數也帶參數。最複雜的狀況。orm

def log(func): #func爲裝飾器的參數
    print"execute log"
    def use_log(func): #func爲cal的函數地址
        print "execute use log"
        print func #func爲cal的函數地址
        def wrapper(param): #param爲cal的參數
            print "start"
            func(param)
            print "end"
            return
        return wrapper
    return use_log

@log('test')
def cal(param):
    print "1+2"

result = cal('cal')

#執行的結果爲:
execute log
execute use log
<function cal at 0x7f23bbc6d6e0>
start
1+2
end

 

通過上面的分析以後,再看flask中使用的是哪一種狀況:

樣例代碼:

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello():
    print 'execute hello function'
    return 'Hello, World!'

@app.route('/')的代碼以下:

 

    def route(self, rule, **options):
        """A decorator that is used to register a view function for a
        given URL rule.  This does the same thing as :meth:`add_url_rule`
        but is intended for decorator usage::

            @app.route('/')
            def index():
                return 'Hello World'

        For more information refer to :ref:`url-route-registrations`.

        :param rule: the URL rule as string
        :param endpoint: the endpoint for the registered URL rule.  Flask
                         itself assumes the name of the view function as
                         endpoint
        :param options: the options to be forwarded to the underlying
                        :class:`~werkzeug.routing.Rule` object.  A change
                        to Werkzeug is handling of method options.  methods
                        is a list of methods this rule should be limited
                        to (``GET``, ``POST`` etc.).  By default a rule
                        just listens for ``GET`` (and implicitly ``HEAD``).
                        Starting with Flask 0.6, ``OPTIONS`` is implicitly
                        added and handled by the standard request handling.
        """
        def decorator(f): 
            endpoint = options.pop('endpoint', None)
            self.add_url_rule(rule, endpoint, f, **options)
            print "this param has been accessed"
            return f
	return decorator

能夠看到裝飾器的參數爲‘/’,被修飾的函數爲:hello(),因此這裏屬於第二種狀況,即便不調用hello()函數,decorator的函數體也是被執行的,也就是說,只要使用裝飾器添加了路由規則,那麼就會被加入到map中造成映射關係。

相關文章
相關標籤/搜索