裝飾器

關於裝飾器咱們先來了解了解什麼是閉包閉包

0X01app

閉包概念函數

closure:內部函數中對enclosing做用域的變量進行引用spa

 

0X02指針

看段小Democode

def func(val):def in_func():
        print (val)
    in_func()
    return in_func

f = func(89)
f()

咱們首先能夠看到在func函數中定義了一個函數in_func,那麼調用func函數返回in_func函數。對象

從C語言角度講就是返回了一個函數指針,但是咱們看看運行結果blog

89
89

f()函數的返回結果是89作用域

func函數調用完成從C語言來角度來講調用棧清除,爲何f()函數還能89呢?class

0X03

首先咱們應該瞭解的是在Python中與C不一樣的是Python函數是一種對象

那麼看看val與函數f()的地址

def func(val):
    print ('%x'%id(val))
    def in_func():
        print (val)
    in_func()
    return in_func

f = func(89)
f()
print (f.__closure__)

運行結果以下

2ff8598
89
89
(<cell at 0x03025650: int object at 0x02FF8598>,)

咱們發現地址都是0X02FF8598! 

那麼閉包實際就是內置函數把引用的變量放入了本身函數屬性中進行返回

 

0X04


既然值能夠做爲函數屬性與函數一塊兒返回,那麼函數也能夠做爲另函數屬性返回

def dec(func):
    def in_dec(*arg):
        print 'In dec'
        if len(arg) == 0:
            return 0
        for val in arg:
            if not isinstance(val, int):
                return 0
        return func(*arg)
    return in_dec


def my_sum(*arg):
    return sum(arg)


my_sum = dec(my_sum)

print my_sum(1,2,3,4,5,6)

如上所示,其實裝飾器也就是閉包的一種。

 

綜上所述
1.裝飾器用來裝飾函數
2.返回一個函數對象
3.被裝飾函數標識符指向返回的函數對象

 

0X05

無參數裝飾器

def dec(func):
    def in_dec(*arg):
        print 'In dec'
        if len(arg) == 0:
            return 0
        for val in arg:
            if not isinstance(val, int):
                return 0
        return func(*arg)
    return in_dec


@dec #my_sum = dec(my_sum)
def my_sum(*arg):
    return sum(arg)

print my_sum(1,2,3,4,5,6)

 

對照上個閉包來看@dec的做用就是 執行了my_sum = dec

 

0X06

有參數裝飾器

有參數裝飾器相對於無參數裝飾器來講就至關於多了一層嵌套

 

def log(prefix):
    def log_decorator(f):
        def wrapper(*args, **kw):
            print '[%s] %s()...' % (prefix, f.__name__)
            return f(*args, **kw)
        return wrapper
    return log_decorator

@log('DEBUG')
def test():
    pass
print test()

咱們把@log('DEBUG')進行展開

my_func = log('DEBUG')(my_func)

上面的語句看上去仍是比較繞,再展開一下:

log_decorator = log('DEBUG')
my_func = log_decorator(my_func)

上面的語句又至關於:

log_decorator = log('DEBUG')
@log_decorator
def my_func():
    pass

 

本質上就是多返回了一層裝飾器而已

相關文章
相關標籤/搜索