參考老師:http://www.cnblogs.com/wupeiqi
lambda表達式
學習條件運算時,對於簡單的 if else 語句,可以使用三元運算來表示,即:
# 普通條件語句 if 1 == 1: name = ‘luotianshuai' else: name = 'shuaige' # 三元運算 name = 'luotianshuai' if 1 == 1 else 'shuaige' #這個就是if else的一個簡寫。 #if 條件成立的時候name為'luotianshuai' 不成立的時候為:'shuaige' ,語法糖!
那么函數有沒有他的簡寫呢?也是有的lambda表達式!
lambda 和if else的三元運算一樣,是為了簡化函數,但是:
1、只能做簡單的操作
2、自動return
看下面兩個函數的對比:
'''正常函數''' def func(arg): return arg + 1 result = func(100) print result '''lambda表達式''' func2 = lambda a: a + 1 result = func2(10000) #這里調用函數的時候就是lambda表達式左邊的等號就是他函數的調用! print result #執行結果: #101 #10001
內置函數 二
一、map
遍歷序列,對序列中每個元素進行操作,最終獲取新的序列。
解釋:
在Python中,最基本的數據結構是序列(sequence)。序列中的每個元素被分配一個序號——即元素的位置,也稱為索引。第一個索引是 0,第二個則是 1,以此類推。序列中的最后一個元素標記為 -1,倒數第二個元素為 -2,一次類推。
Python包含 6 中內建的序列,包括列表、元組、字符串、Unicode字符串、buffer對象和xrange對象。

'''例子1''' li = [11,22,33] def func1(arg): return arg + 1 #這里乘除都可以 new_list = map(func1,li) #這里map調用函數,函數的規則你可以自己指定,你函數定義成什么他就做什么操作! print new_list 輸出結果:[12, 23, 34] '''例子2''' li = ['shuaige','nihao',] def func1(arg): return '%s test string' % arg #或者使用+進行拼接萬惡的+能不用最好不用他會在內存中開辟新的空間! new_strlist = map(func1,li) print new_strlist 輸出結果:['shuaige test string', 'nihao test string'] '''例子3''' li = 'abcdefg' def func1(arg): return '%s test string' % arg new_list = map(func1,li) print new_list #結果:['a test string', 'b test string', 'c test string', 'd test string', 'e test string', 'f test string', 'g test string']
使用lambda表達式:

li = [11,22,33,44,55] new_li = map(lambda a:a + 100,li) print new_li #輸出結果: [111, 122, 133, 144, 155] #多個列表操作: l1 = [11,22,33,44,55] l2 = [22,33,44,55,66] l3 = [33,44,55,66,77] print map(lambda a1,a2,a3:a1+a2+a3,l1,l2,l3) #輸出結果: [66, 99, 132, 165, 198] #這里需要注意如果使用map函數列表中的元素必須是相同的才可以!否則就會報下面的錯誤! #TypeError: unsupported operand type(s) for +: 'int' and 'NoneType',如果看下面 l1 = [11,22,33,44,55] l2 = [22,33,44,55,66] l3 = [33,44,55,66,] #l3的數據少一個,如果元素里的元素為空那么他調用的時候這個元素就是None
二、filter
對於序列中的元素進行篩選,最終獲取符合條件的序列!
li = [11,22,33,44,55,66,77,88] print filter(lambda a:a>33,li) 輸出結果:[44, 55, 66, 77, 88]
三、reduce
對於序列內所有元素進行累計操作
li = [1,2,3,4,5,6,7,8] result = reduce(lambda a1,a2:a1+a2,li) #累乘、除、加、減 print result # reduce的第一個參數,函數必須要有兩個參數,因為他是兩兩進行操作 # reduce的第二個參數,要循環的序列 # reduce的第三個參數,初始值 #初始值 li = [1,2,3,4,5,6,7,8] result = reduce(lambda a1,a2:a1+a2,li,100000) #累乘、除、加、減 print result
默認參數:
yield生成器
yield和return的區別:
yield跳出函數后會記錄當前函數的狀態當下次調用的時候,從記錄的狀態開始!
return后將直接跳出函數!
1、對比range 和 xrange 的區別
>>> print range(10) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> print xrange(10) xrange(10)
如上代碼所示,range會在內存中創建所有指定的數字,而xrange不會立即創建,只有在迭代循環時,才去創建每個數組。
看下下面的例子:(自定義生成器)
def mrange(arg): seed = 0 while True: seed = seed +1 if seed > arg: return else: yield seed for i in mrange(10): print i
冒泡算法
需求:請按照從小到大對列表 [13, 22, 6, 99, 11] 進行排序
思路:相鄰兩個值進行比較,將較大的值放在右側,依次比較!
冒泡算法原理圖:
冒泡算法實例:
列表中有5個元素兩輛進行比較,然后用中間值進行循環替換!
既然這樣,既然這樣我們還可以用一個循環把上面的循環進行在次循環,用表達式構造出內部循環!
li = [13,22,6,99,11] for n in range(1,len(li)): for m in range(len(li)-n): num1 = li[m] num2 = li[m+1] if num1 > num2: temp = li[m] li[m] = num2 li[m+1] = temp print li
讓的原理和下面一樣:

li = [13,22,6,99,11] for m in range(4): #等價於:for m in range(len(li)-1) num1 = li[m] num2 = li[m+1] if num1 > num2: temp = li[m] li[m] = num2 li[m+1] = temp print li for m in range(3): #等價於:for m in range(len(li)-2) num1 = li[m] num2 = li[m+1] if num1 > num2: temp = li[m] li[m] = num2 li[m+1] = temp print li for m in range(2): #等價於:for m in range(len(li)-3) num1 = li[m] num2 = li[m+1] if num1 > num2: temp = li[m] li[m] = num2 li[m+1] = temp print li for m in range(1): #等價於:for m in range(len(li)-4) num1 = li[m] num2 = li[m+1] if num1 > num2: temp = li[m] li[m] = num2 li[m+1] = temp print li
裝飾器
裝飾器是函數,只不過該函數可以具有特殊的含義,裝飾器用來裝飾函數或類,使用裝飾器可以在函數執行前和執行后添加相應操作。
簡單的來說在不修改原函數的情況下,在對原函數進行包裝!
一、初創公司有N個業務部門,1個基礎平台部門,基礎平台負責提供底層的功能,如:數據庫操作、redis調用、監控API等功能。業務部門使用基礎功能時,只需調用基礎平台提供的功能即可。如下:
############### 基礎平台提供的功能如下 ############### def f1(): print 'f1' def f2(): print 'f2' def f3(): print 'f3' def f4(): print 'f4' ############### 業務部門A 調用基礎平台提供的功能 ############### f1() f2() f3() f4() ############### 業務部門B 調用基礎平台提供的功能 ############### f1() f2() f3() f4()
目前公司有條不紊的進行着,但是,以前基礎平台的開發人員在寫代碼時候沒有關注驗證相關的問題,即:基礎平台的提供的功能可以被任何人使用。現在需要對基礎平台的所有功能進行重構,為平台提供的所有功能添加驗證機制,即:執行功能前,先進行驗證。
老大把工作交給 Low B,他是這么做的:
跟每個業務部門交涉,每個業務部門自己寫代碼,調用基礎平台的功能之前先驗證。誒,這樣一來基礎平台就不需要做任何修改了。
當天Low B 被開除了...
老大把工作交給 Low BB,他是這么做的:
只對基礎平台的代碼進行重構,讓N業務部門無需做任何修改

############### 基礎平台提供的功能如下 ############### def f1(): # 驗證1 # 驗證2 # 驗證3 print 'f1' def f2(): # 驗證1 # 驗證2 # 驗證3 print 'f2' def f3(): # 驗證1 # 驗證2 # 驗證3 print 'f3' def f4(): # 驗證1 # 驗證2 # 驗證3 print 'f4' ############### 業務部門不變 ############### ### 業務部門A 調用基礎平台提供的功能### f1() f2() f3() f4() ### 業務部門B 調用基礎平台提供的功能 ### f1() f2() f3() f4()
過了一周 Low BB 被開除了...
老大把工作交給 Low BBB,他是這么做的:
只對基礎平台的代碼進行重構,其他業務部門無需做任何修改

############### 基礎平台提供的功能如下 ############### def check_login(): # 驗證1 # 驗證2 # 驗證3 pass def f1(): check_login() print 'f1' def f2(): check_login() print 'f2' def f3(): check_login() print 'f3' def f4(): check_login() print 'f4'
老大看了下Low BBB 的實現,嘴角漏出了一絲的欣慰的笑,語重心長的跟Low BBB聊了個天:
老大說:
寫代碼要遵循開發封閉原則,雖然在這個原則是用的面向對象開發,但是也適用於函數式編程,簡單來說,它規定已經實現的功能代碼不允許被修改,但可以被擴展,即:
- 封閉:已實現的功能代碼塊
- 開放:對擴展開發
如果將開放封閉原則應用在上述需求中,那么就不允許在函數 f1 、f2、f3、f4的內部進行修改代碼,老板就給了Low BBB一個實現方案:
def w1(func): def inner(): # 驗證1 # 驗證2 # 驗證3 return func() return inner @w1 def f1(): print 'f1' @w1 def f2(): print 'f2' @w1 def f3(): print 'f3' @w1 def f4(): print 'f4'
對於上述代碼,也是僅僅對基礎平台的代碼進行修改,就可以實現在其他人調用函數 f1 f2 f3 f4 之前都進行【驗證】操作,並且其他業務部門無需做任何操作。
Low BBB心驚膽戰的問了下,這段代碼的內部執行原理是什么呢?
老大正要生氣,突然Low BBB的手機掉到地上,恰恰屏保就是Low BBB的女友照片,老大一看一緊一抖,喜笑顏開,交定了Low BBB這個朋友。詳細的開始講解了:
單獨以f1為例:
def w1(func): def inner(): print 'gongneng1' func() print 'gongneng2' return inner @w1 def f1(): print 'f1' f1()
當執行的時候,python是由上到下執行的,首先執行到def w1(func):這里把def w1(func)加載到內存
當執行到@w1的時候@w1是python的語法糖!他會把他下面的函數進行封裝。
把f1這個函數作為def w1(func)的參數傳進去!就是:f1()=w1(f1)
然后def w1(func): == w1(f1)就會執行:
def inner(): print 'gongneng1' func() #func() == f1()“原函數” print 'gongneng2' return inner #然后把封裝后的函數輸出給原函數
@w1就相當於做了一個替換
def f1() <==> def inner()
@w1 def f1(): # ==def inner() : print 'f1' # print 'gongneng1' # func() # print 'gongneng2'
二、被裝飾的函數如果有參數呢?
def w1(func): def inner(arg): # 驗證1 # 驗證2 # 驗證3 return func(arg) return inner @w1 def f1(arg): print 'f1' 一個參數 ################################ def w1(func): def inner(arg1,arg2): # 驗證1 # 驗證2 # 驗證3 return func(arg1,arg2) return inner @w1 def f1(arg1,arg2): print 'f1' 兩個參數 ################################ def w1(func): def inner(arg1,arg2,arg3): # 驗證1 # 驗證2 # 驗證3 return func(arg1,arg2,arg3) return inner @w1 def f1(arg1,arg2,arg3): print 'f1' 三個參數
用動態參數搞定!
def w1(func): def inner(*args,**kwargs): # 驗證1 # 驗證2 # 驗證3 return func(*args,**kwargs) return inner @w1 def f1(arg1,arg2,arg3): print 'f1'
三、一個函數可以被多個裝飾器裝飾嗎?
def w1(func): def inner(*args,**kwargs): print 'gongneng1' func(*args,**kwargs) print 'gongneng2' return inner def w2(func): def inner(*args,**kwargs): print 'gongneng3' func(*args,**kwargs) print 'gongneng4' return inner @w1 @w2 def f1(arg,arg2,arg3): print arg,arg2,arg3 f1('nihao','tianshuai','shuaige')
輸出結果:
gongneng1 gongneng3 nihao tianshuai shuaige gongneng4 gongneng2
這個被多個裝飾器裝飾,其實就是套完一層在套一層!勿把自己繞進去!
四、還有什么更吊的裝飾器嗎?
def Filter(a1,a2): def outer(main_func): def wrapper(request,kargs): print a1 main_result = main_func(request,kargs) print a2 return main_result return wrapper return outer @Filter(f5, f6) def Index(request,kargs): print 'index' ''' 1、第一步:把def Filter(a1,a2): 加載到內存 2、第二步:@Filter(f5, f6) == 調用了裝飾器 == @outer 然后返回給函數 3、第散步:執行outer函數並返回給index函數 Index == wrapper 4、執行wrapper 函數,這樣做的意義就是除了原函數給的參數外,裝飾器也可以調用自己定義的參數 '''
這樣做的意義就是除了原函數給的參數外,裝飾器也可以調用自己定義的參數