在python語言中“裝飾器”模式被設(shè)計(jì)成語言內(nèi)置的設(shè)計(jì)模式季眷,使得使用該模式變得簡單,僅僅需要在目標(biāo)函數(shù)前使用‘@’符號(hào)加裝飾器名就能達(dá)到目的。但如果同一個(gè)目標(biāo)函數(shù)需要進(jìn)行多次裝飾,那么調(diào)用目標(biāo)函數(shù)時(shí)裝飾器的執(zhí)行順序是怎樣的呢肉迫?
這里有個(gè)例子,有個(gè)目標(biāo)函數(shù)叫l(wèi)unch稿黄,中午調(diào)用一下來決定午飯吃什么
# coding: utf-8
import random
# 飯館
restaurants = {
'KFC': ['hamburger', 'chicken wings', 'ice cream', 'salmon fish'],
'xiapu': ['Beef hotpot', 'Mutton hotpot', 'Tomato hotpot'],
}
def chose_food(f):
print 'decorator: chose_food enter'
def func(*args, **kwargs):
print 'decorator: chose_food::func enter'
a_rstrnt = args[0]
food = random.choice(restaurants[a_rstrnt])
return f(food, *args, **kwargs)
print 'decorator: chose_food exit'
return func
def restaurant(f):
print 'decorator: restaurant enter'
def func(*args, **kwargs):
print 'decorator: restaurant::func enter'
a_rstrnt = random.choice(restaurants.keys())
return f(a_rstrnt, *args, **kwargs)
print 'decorator: restaurant exit'
return func
@restaurant
@chose_food
def lunch(food, addr, then):
print "We're going to {} for '{}', then {}".format(addr, food, then)
lunch('have a rest')
輸出結(jié)果
decorator: chose_food enter
decorator: chose_food exit
decorator: restaurant enter
decorator: restaurant exit
decorator: restaurant::func enter
decorator: chose_food::func enter
We're going to KFC for 'hamburger', then have a rest
通過打印結(jié)果可以看出裝飾器裝飾的順序是“從下到上”依次執(zhí)行喊衫,而執(zhí)行的順序是“從上到下”。
原因是裝飾器在這個(gè)例子中起的作用是對(duì)目標(biāo)函數(shù)包裝杆怕,兩個(gè)裝飾器裝飾過后族购,是這種情形:
lunch(then){} = deco.restaurant(then) {
deco:chose_food(rstrnt, then) {
lunch(food, rstrnt, then){}
}
}
lunch(then)
被調(diào)用時(shí)自然按照由外到內(nèi)的順序執(zhí)行壳贪。