Python3(十) 函數式編程: 匿名函數、高階函數、裝飾器

一.匿名函數

1.定義:定義函數的時候不須要定義函數名編程

2.具體例子:app

#普通函數函數式編程

def add(x,y):
 
    return x + y

#匿名函數函數

lambda x,y: x + y

調用匿名函數:編碼

f = lambda x,y: x + y    #賦值後能夠調用
 
print(f(1,2)

lambda中(也就是:後面)只能進行簡單的表達式操做,不能進行賦值操做。spa

二. 三元表達式

格式爲:條件爲真時返回的結果 if 條件判斷 else 條件爲假時返回的結果code

x = 2
 
y = 1
 
r = x if x > y else y
 
print(r)
 
#2

三元表達式在lambda中運用比較多。blog

三.map類

1.定義:map(函數,序列),把序列中全部值依次傳到函數中並依次接受返回結果組成一個list。io

              實際上是一個函數的映射。function

2.求平方:

list_x = [1,2,3,4,5,6,7,8]
 
 
def square(x):
 
    return x * x
 
 
r = map(square,list_x)
 
print(list(r))
 
#[1, 4, 9, 16, 25, 36, 49, 64]

四.map與lambda

將map和lambda函數結合:

 1

list_x = [1,2,3,4,5,6,7,8]
 
r = map(lambda x: x * x,list_x)
 
print(list(r)

2 接受多個參數:

list_x = [1,2,3,4,5,6,7,8]
 
list_y = [1,2,3,4,5,6,7,8]
 
r = map(lambda x,y: x * x + y,list_x,list_y)
 
print(list(r))

注意:若個數不相等,不會報錯,但只能計算到最少的那位

五.reduce

1.

 2. reduce運算的規則:作連續的計算,連續的調用lambda表達式。

   reduce下的函數必定要有兩個參數。

3.例子:

from functools import reduce
 
list_x = [1,2,3,4,5,6,7,8]
 
r = reduce(lambda x,y:x + y,list_x)
 
print(r)
 
#36

運算過程:初始取前兩位,以後將計算結果做爲x傳進去繼續順序取:

((((((1 + 2)+3) + 4)+ 5)+6)+7)+8

 

4.注意點:

  • 繼續作什麼操做是lambda肯定的,不只只可以相加。
  • 最後一位能夠設定初始值,在第一次計算中就進行計算了:

         eg:r = reduce(lambda x,y:x + y,list_x,10)

 

六. filter

1.filter能夠過濾掉不符合規則的數據。

 

2.例子:

 剔除數據爲0的元素:

list_x = [1,0,0,1,0,1,1,0,1]
 
r = filter(lambda x: True if x == 1 else False,list_x)
 
print(list(r))
 
#[1, 1, 1, 1, 1]

簡化爲:

list_x = [1,0,0,1,0,1,1,0,1]
 
r = filter(lambda x: x ,list_x)
 
print(list(r))
 
#[1, 1, 1, 1, 1]

filter返回值的要是真和假才能完成過濾

 

七.命令式編程vs函數式編程

  命令式編程涉及到 def  if else for

  函數式編程涉及到 map reduce filter lambda(算子)

八. 裝飾器 一

import time
 
def f1():
 
    print(time.time())
 
    print('This is a function')
 
 
 
f1()
 
#1532404967.3804688    #Unix時間戳
 
 This is a function

若是不少的函數都要獲取時間的功能:

import time
 
def f1():
 
    print('This is a function')
 
 
def f2():
 
    print('This is a function')
 
 
def print_current_time(func):
 
    print(time.time())
 
    func()

 
print_current_time(f1)
 
print_current_time(f2)

這種需求變動方案的缺點:打印時間的需求是屬於每一個函數自己的,並非新增長的,並無體現函數自己的特性。

這就是裝飾器所要解決的問題。

裝飾器 二

編寫裝飾器:

import time
 
def decorator(func):
 
    def wrapper():
 
        print(time.time())
 
        func()
 
    return wrapper

 
def f1():
 
    print('This is a function')
 
f = decorator(f1)    #f獲得了return的wrapper
 
f()

裝飾器 三

語法塘:

import time
 
 
def decorator(func):
        def wrapper():
 
        print(time.time())
 
        func()
 
    return wrapper
 
 
 
@decorator    #@符號
 
def f1():
 
    print('This is a function')
 
f1()

沒有改變調用的邏輯也沒有改變函數編碼。是裝飾器的意義所在。

@decorator至關於對f1()裝飾。

裝飾器 四

1.帶參函數的裝飾器:

import time
 
def decorator(func):
 
    def wrapper(func_name):
 
        print(time.time())
 
        func(func_name)
 
    return wrapper
 
 
@decorator
 
def f1(func_name):
 
    print('This is a function named' + func_name)
 

f1('test_func')

2.若多個函數接受不一樣數量的參數:

import time
 
def decorator(func):
 
    def wrapper(*args):
 
        print(time.time())
 
        func(*args)
 
    return wrapper
 
@decorator
 
def f1(func_name):
 
    print('This is a function named' + func_name)
 
@decorator
 
def f2(func_name1,func_name2):
 
    print('This is a function named'+func_name1 )
    print('This is a function named'+ func_name2)
 
 
 
f1('test_func')
 
f2('test_func1','test_func2')    #能夠支持不一樣參數個數的函數

裝飾器 五

1.*args不支持**關鍵字參數

支持關鍵字參數:

import time
 
 
 
def decorator(func):
 
    def wrapper(*args,**kw):    #加入**kw,較爲完整
 
        print(time.time())
 
        func(*args,**kw)
 
    return wrapper
 
 
 
@decorator
 
def f1(func_name):
 
    print('This is a function named' + func_name)
 
 
 
@decorator
 
def f2(func_name1,func_name2):
 
    print(func_name1 + func_name2)
 
 
 
@decorator
 
def f3(func_name1,func_name2,**kw):
 
    print(func_name1 + func_name2)
 
    print(kw)
 
 
 
f1('test_func')
 
f2('123','234')
 
f3('123','234',a = 1, b = 2,c = '123')
 
 
 
#1532408656.565761
 
#This is a function namedtest_func
 
#1532408656.5667255
 
#123234
 
#1532408656.5677273
 
#123234
 
#{'a': 1, 'b': 2, 'c': '123'}

2.

def decorator(func):

    def wrapper(*args,**kw):    #加入**kw,較爲完整

        print(time.time())

        func(*args,**kw)

    return wrapper

func(*args,**kw)這個形式,不管什麼方式均可以調用。

裝飾器 六

若是想對某個封裝單元修改,能夠加上裝飾器。

不須要破壞代碼實現,易於代碼複用。

一個函數可以有多個裝飾器。

須要驗證身份的函數上加上專門的裝飾器之類的用途。

相關文章
相關標籤/搜索