函式的巢狀是指在函式內再定義乙個函式,舉個例子:
def
outter()
: name=
'jack'
#被下層函式使用
age=
20#被下層函式使用
address=
'yn'
#被下層函式做返回值
height=
'178'
#沒有被下層函式使用
definner()
: new_name=name[0:
3]new_age=age+
1 inner_l=
locals()
inner_g=
globals()
return address,inner_l#address使用outter的
return inner#返回不是值物件,是函式物件
注意到外層函式返回的是內層函式物件,如果我呼叫:
inner=outter()
結果為:
<
locals
>
.inner(
)>
可以看出inner是outter的locals()空間下的函式物件,再回顧以前說過,函式名返回的只是函式本身,如果要徹底呼叫inner,需要寫inner(),即outter()();注意一下:outter()只是inner本身觀察內層函式inner,裡面有一句:inner_l=locals()
,然後這個inner_l在內層函式結尾時被return了,這說明我們只要呼叫了inner將可以檢視到內層函式的locals()命名空間,所以呼叫inner()看一下:也就是呼叫outter()()
(
'yn',
)
元組裡第乙個』yn『應該是address,第二個字典就是inner的locals()空間,發現沒有外部函式的height(注意內部函式沒有用到height),而其他在外部函式中用到的物件都出現在了inner的空間裡,這就是閉包;
可以dir()檢視一下內層函式物件包含的物件:
inner=outter(
)dir(inner)
發現有乙個物件叫inner.__closure__
,我們檢視這個物件的內容有:
(
:str
object at 0x7f27152d86c0
>
,:int
object at 0xa6a000
>
,:str
object at 0x7f27152d8688
>
)
可見,__closure__中儲存了inner需要用到的外部變數str:name,int:age,str:address,而height沒有用到,所以不在__closure__裡面,這就是閉包,閉包指的是:內部函式可以使用外部函式的變數
現在可以補充e空間了,e就是指閉包物件,只有出現巢狀函式情況才有e空間,訪問會從內層函式的locals()開始,到外部函式的locals()即閉包enclose空間,再到globals(),最後搜尋到builtins;
當然,enclose空間並不完全指外層函式的locals(),準確來說,是外層函式與內層函式相交的那部分物件才是enclose空間
在前面巢狀函式的基礎上,看懂裝飾器就會變得很容易,在開始之前,先想想為什麼會需要裝飾器?
出現它的目的,主要是用於為不同的函式增加相同的功能,減少**重複,假設有以下函式:
def
func1()
:print
("1"
)def
func2()
:print
("2"
)def
func3()
:print
("3"
)
現在要給它們加上同樣的功能,我在剛接觸python時,會選擇無腦地為每個函式重複寫上同樣的功能:
def
func1()
:print
("1"
)print
("add func"
)def
func2()
:print
("2"
)print
("add func"
)def
func3()
:print
("3"
)print
("add func"
)
在發現函式也可以作為引數後,我想到了乙個方法,看似簡單了一點(注意這不是巢狀函式,因為我沒有在函式內定義函式):
def
add_func
(func)
:print
("add func"
)return func
#呼叫:引數更換函式名即可,如func1,func2,func3都行
add_func(func1)()
"""輸出
add func
1"""
但是總感覺不夠美觀,於是開始使用裝飾器,首先裝飾器函式的定義需要遵循格式,它是使用巢狀函式定義的:
def
outter
(func)
:print
("可以在這裡執行增添功能"
)def
inner()
:print
("也可以在這裡執行增添功能"
)#執行被裝飾的函式
func(
)return
none
return inner#外層函式必須返回內層函式物件
#注意裝飾器的使用格式
@outter
defmyfunc()
:print
("這裡執行被裝飾的函式"
)#呼叫:直接寫函式名
myfunc(
)
結果如下:
可以看出,裝飾器讓函式新增功能的定義和呼叫更加簡潔,在為函式增加功能的同時,不改變函式的呼叫,使**易於維護
第六課 深入函式
在lua中,函式是一種 第一類值 和數字 字串等一樣,具有相同的權利 它們具有特定的詞法域 乙個函式可以巢狀在另乙個函式中,內部函式可以訪問外部函式中的變數 函式式語言,函式式程式設計。在lua中有乙個容易混淆的概念是,函式與其他所有值一樣 都是匿名的,即它們都沒有名稱。當討論乙個函式名時 例如pr...
python第六課 字典
字典是另一種可變容器模型,且可儲存任意型別物件.字典的每個鍵值 key value 對用冒號 分割,每個對之間用逗號 分割,整個字典包括在花括號 中,格式如下所示 dict 鍵必須是唯一的,但值則不必.不允許同乙個鍵出現兩次建立時如果同乙個鍵被賦值兩次,後乙個值會被記住並且覆蓋上乙個值 值可以取任何...
第六課 字型
a.字型系列 font family times new roman times,serif b.字型樣式 font style normal 正常 正常顯示文字 font style italic 斜體 以斜體字顯示的文字 font style oblique 傾斜的文字 文字向一邊傾斜 和斜體非...