002_第三部分_[函數 / 高階函數 / 裝飾器]

一.高階函數:

  • 順序排序

enumerate([1,2 ,3 , 4, 5])
for idx, item in enumerate([1, 2, 3, 4]):
    print(idex)
    print(item)


def sort(*args):
    ret = []
    for item in args:
        for i, v in enumerate(ret):
            if item > v:
                ret.insert(i,item)
                break
        else:
            ret.append(item)
    return ret

sort(3, 1, 2, 5)
  • 逆序排列

def sort(f, *args):
    ret = []
    for item in args:
        for i, v in enumerate(ret):
            if f:
                if item >= v:
                    ret.insert(i,item)
                    break
            else:
                if item <= v:
                    ret.insert(i,item)
                    break
        else:
            ret.append(item)
    return ret

sort(True, 3, 1, 2, 5)
  • 高階函數

def sort(cmp, *args):
    ret = []
    for item in args:
        for i, v in enumerate(ret):
            if cmp(item, v):
                ret.insert(i, item)
                break
        else:
            ret.append(item)
    return ret
def cmp1(x, y):
    return x >= y
def cmp2(x, y):
    return x <= y
sort(cmp1, 3, 1, 2, 5)
[5, 3, 2, 1]

二.特殊函數[內置函數]:

1.filter 根據布爾返回值,輸出返回值爲True的數值,相當於過濾器。

格式:filter(function, iterable)   ,返回的是個對象

def bigger_5(x):
    if x > 5:
        return True
    return False         #相當於 else:return False                                                                   
filter(bigger_5, range(10))
list(filter(bigger_5, range(10)))
>[6, 7, 8, 9]

#列表解析實現
[i for i in list(range(10)) if i > 5]

2.map 輸出函數中的返回值的一個迭代器:

    格式:map( func, seq1[, seq2...] )

 例子1:

def bigger_5(x):
    if x > 5:
        return True
    return False
map(bigger_5, range(10))
list(map(bigger_5, range(10)))
>[False, False, False, False, False, False, True, True, True, True]

 例子2:  

def inc(x):
    return x + 1
list(map(inc,[1, 2, 3, 4]))
>[2, 3, 4, 5]
list(map(inc,range(3)))
>[1, 2, 3]

 例子3: 

list(map(lambda x:x + 1,range(3)))
>[1, 2, 3]

  例子4:

a = map(lambda x:x + 1,range(3))
next(a)
>1
next(a)
>2
next(a)
>3
next(a)
>StopIteration

3.reduce

格式:reduce( func, seq[, init] )

reduce函數即爲化簡,它是這樣一個過程:每次迭代,將上一次的迭代結果(第一次時爲init的元素,如沒有init則爲seq的第一個元素)與下一個元素一同執行一個二元的func函數。在reduce函數中,init是可選的,如果使用,則作爲第一次迭代的第一個元素使用。

n = 5
print reduce(lambda x, y: x * y, range(1, n + 1))  # 120
m = 2
n = 5
print reduce( lambda x, y: x * y, range( 1, n + 1 ), m )  # 240

4.lambda

def sort(cmp, *args):
    ret = []
    for item in args:
        for i, v in enumerate(ret):
            if cmp(item, v):
                ret.insert(i, item)
                break
        else:
            ret.append(item)
    return ret
sort(lambda x, y: x >= y, 3, 1, 2, 5)

5.函數作爲返回值

def make_ic(f=1):
    def inc(x):
        return x + f
    return inc

inc1 = make_ic(1)
inc1(5)
>6

柯里化:

def bigger(x):
    def inner_bigger(y):
        return y > x
    return inner_bigger

list(filter(bigger(5), range(10)))
>[6, 7, 8, 9]

三.functools庫

1.partial [設置默認參數, 後期任然可以通過關鍵字參數進行傳參]

查看是不是可調用對象:

from functools import partial
import pymysql

callable(bigger_3)
bigger_3 = partial(bigger,y=3)

connect = partial(pymysql.connect, user='root', password='xxxx', database='xxxx', port=3306)

connect(host='127.0.0.1')

四.裝飾器

 裝飾器的本質就是一個函數,這個函數接收一個函數作爲參數, 返回一個函數,通常,返回的這個函數,是對傳入的函數執行前後增加了一些語句,所以叫做裝飾;


  • 普通裝飾器

#第一種寫法

def timeit(fn):
    def wrap(*args, **kwargs):
        start = time.time()
        ret = fn(*args,**kwargs)
        print(time.time() - start)
        return ret
    return wrap

def sleep(x):
    time.sleep(x)

timeit(sleep)(3)

第二種方法:

def timeit(fn):
    def wrap(*args, **kwargs):
        start = time.time()
        ret = fn(*args,**kwargs)
        print(time.time() - start)
        return ret
    return wrap
@timeit
def sleep(x):
    time.sleep(x)
sleep(3)
time.time() //得到的是一個自然的時間
time.clock() //得到的是一個cpu執行時間,佔用cpu的時間;

2.帶參數的裝飾器

import time
def timeit(process_time=False):
    cacl = time.clock if process_time else time.time
    def inner_timeit(fn):
        def wrap(*args, **kwargs):
            start = cacl
            ret = fn(*args, **kwargs)
            print(cacl() - start)
            return ret
        return wrap
    return inner_timeit
@timeit(True)
def sleep(x):
    time.sleep(x)
sleep(3)
import time
def timeit(process_time=False):
    cacl = time.clock if process_time else time.time
    def inner_timeit(fn):
        def wrap(*args, **kwargs):
            start = cacl()
            ret = fn(*args, **kwargs)
            print(cacl() - start)
            return ret
        return wrap
    return inner_timeit
def sleep(x):
    time.sleep(x)
timeit(False)(sleep)(3)  等價 timeit()(sleep)(3)
timeit(True)(sleep)(3)
import time
def timeit(process_time=False):
    cacl = time.clock if process_time else time.time
    def inner_timeit(fn):
        def wrap(*args, **kwargs):
            start = cacl()
            ret = fn(*args, **kwargs)
            print(cacl() - start)
            return ret
        return wrap
    return inner_timeit
@timeit(True)  or @timeit()   or @timeit(False)
def sleep(x):
    time.sleep(x)
sleep(3)
#帶參數的裝飾器的基本結構
def make_timeit():
    def timeit():
        def inner_timeit(fn):
            def wrap(*args, **kwargs):
                return fn(*args, **kwargs)
            return wrap
        return inner_timeit
    return timeit
@make_timeit()()     //這樣寫是有問題的,因爲python的語法解析器只支持帶一個參數
正確寫法如下
time_2 = make_timeit()
@time_2()
或者
time_2 = make_timeit()()
@time_2
def fn():
    pass

3.裝飾器的實際應用:

flask使用了大量的裝飾來做路由

[flask.pocoo.org]


#利用裝飾器進行權限控制

def check(allows):
    def deco(fn):
        def wrap(username, *args, **kwargs):
            if username in allows:
                return fn(username, *args, **kwargs)   //這一行需要和wrap這一行一一對應起來
            return "not allow"
        return wrap
    return deco
@check(["comyn", "mage"])
def private(username):
    print("congratulation")
    
private("comyn")

4.函數的字文檔[wraps]:

def test():
        '''
        this is test
        @return None
        '''
        pass
help(test)
>Help on function test in module __main__:
test()
    this is test
    @return None
import time
def timeit(process_time=False):
    cacl = time.clock if process_time else time.time
    def inner_timeit(fn):
        def wrap(*args, **kwargs):
            start = cacl()
            ret = fn(*args, **kwargs)
            print(cacl() - start)
            return ret
        wrap.__name__ = fn.__name__
        wrap.__doc__ = fn.__doc__
        return wrap
    return inner_timeit
@timeit(True)  or @timeit()   or @timeit(False)
def sleep(x):
    '''
        this is test
        '''
sleep.__name__
help(sleep)

# 使用wraps實現函數的字文檔

import time
from functools import wraps
def timeit(process_time=False):
    cacl = time.clock if process_time else time.time
        @wraps()
    def inner_timeit(fn):
        def wrap(*args, **kwargs):
            start = cacl()
            ret = fn(*args, **kwargs)
            print(cacl() - start)
            return ret
        return wrap
    return inner_timeit
@timeit(True)  or @timeit()   or @timeit(False)
def sleep(x):
    '''
        this is test
        '''
sleep.__name__
help(sleep)


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章