【6】裝飾器、閉包、偏函式、變數作用域問題
阿新 • • 發佈:2018-11-10
【一】、裝飾器思想
裝飾器是其實想增加一個函式的功能,但是又不想變動原來函式的程式碼,就用裝飾器。
比如:我們用別人的一個函式,又不是很滿意,所以用裝飾器裝飾一下即可。
def fun1(): print("嘉嘉 is a good man !") def outer(): print("****") fun1() outer()
【二】閉包
什麼是閉包?
閉包:把一個函式當做一個引數傳入另一個函式。本質上是一個返回函式的函式
案例1:簡單的閉包實現裝飾器程式碼
# 簡單的裝飾器 # 即以上起到了裝飾器的作用,但是是寫死了的,如何才能用一個呼叫來實現呢 # 閉包:把一個函式當做一個引數傳入另一個函式。本質上是一個返回函式的函式 print('------------------------我是分割線-------------------------') def fun2(): print("嘉嘉 is a good man !") def outer2(fun): def inner(): print("****") fun() return inner # f代表是裝飾後的返回的加強版的一個函式,並且是要裝飾誰,把誰傳進去。那麼傳入進去的東西被 # inner函式中的內容修飾了。 f=outer2(fun2) print(type(f)) f() ''' 輸出: **** 嘉嘉 is a good man ! '''
其中:
f代表是裝飾後的返回的加強版的一個函式,並且要裝飾誰,把誰傳進去。那麼傳入進去的東西被 # inner函式中的內容修飾了。
案例2:複雜一點的裝飾器
1 # 案例2 :複雜一點的裝飾器 2 def say(age): 3 print("she is %d years old " %(age) ) 4 5 # 寫一個裝飾器 6 def outer(func): 7 definner(age): 8 if age<0: 9 age=0 10 say(age) 11 return inner 12 13 say2=outer(say) 14 # 此時呼叫的say2 其實就是outer函式返回的一個inner函式,say2他本身是函式 15 # 此時傳入age=-5,執行say2函式,其實就是執行記憶體inner這個函式,
16 say2(-5) 17 say2(89) 18 ''' 19 輸出是: 20 she is 0 years old 21 she is 89 years old 22 '''
總結:
4 # 此時呼叫的say2 其實就是outer函式返回的一個inner函式,say2他本身是函式 15
# 此時傳入age=-5,執行say2函式,其實就是執行記憶體inner這個函式,
案例2-改進 :用標準的裝飾器語法來寫的話如下程式碼
# 案例2 改進 標準的裝飾器 @outer #其實這個是等價 say2=outer(say) def say3(age): print("she is %d years old " %(age) ) # 寫一個裝飾器 def outer(func): def inner(age): if age<0: age=0 say(age) return inner # say2=outer(say) 上邊給需要裝飾的函式寫了@ 這句話是可以直接省略的。 say3(-3) #注意:用@裝飾完之後的函式名是不變的。 ''' 輸出是: she is 0 years old '''
案例3-通用裝飾器
此裝飾器是通用版本,就不用擔心傳遞的形參的個數問題啦
# 案例3 改進 通用裝飾器 # 寫一個裝飾器 def outer2(func): def inner2(*args, **kwargs): ''' # 新增需要控制功能的語句塊 if age<0: age=0 ''' print("我是裝飾的程式碼塊") return func(*args,**kwargs) return inner2 @outer2 def say4(age,name): print("she is %d years old ,Her name is %s "%(age,name) ) print("通用裝飾器!") say4(-3,"佳佳") #注意:用@裝飾完之後的函式名是不變的。 ''' 輸出是:
我是裝飾的程式碼塊
she is -3 years old ,Her name is 佳佳
'''
案例1 簡單的偏函式
# 偏函式:其實就是對形參的一個預設值的控制 def int_(str,base=2): return int(str,base) print(int_("1010")) # 輸出:10
# 方法2 引入模組法
import functools
int3=functools.partial(int,base=2)
print(int3("1010"))
# 輸出:10
作用域:
1、區域性作用域
2、全域性作用域
3、內建作用域
<未完待補充!>