1. 程式人生 > >python的函式巢狀機制

python的函式巢狀機制

最近相對來講比較清閒,所以能用一點時間找一些有意思的東西出來,因為之前在用python寫一個簡單的mysql訪問類的時候想用一下單例,所以從網上copy了很多程式碼。有些程式碼用到了python的巢狀函式,但是秉著不熟悉的東西會出錯的錯誤思想,我放棄了用那種看起來更為高大上一點的用法,轉而用了一種簡單的寫法,今天又在一個地方看到了函式巢狀這種用法,覺得很有意思,因為在編譯語言中很少見到,決定研究一下。      python的巢狀函式,單一引數時返回內函式,也就是說,假設巢狀N層,那麼給定M個引數,返回的就是第N-M層的函式體。那都是後話,返回N層,實際上不好操控,用處也不大。我來著重看一下單一巢狀的時候,巢狀函式是怎樣表現的。 打個比方,有一個二維度的需求的場景,二維度這個詞是我自己定義的,代表著一個需求可能有兩種變數,簡單的來講,比如加法。 如果我們想寫加法,怎麼寫?easy,比如我想寫一個將0~100之內的所有數加一起,可能最簡單的寫法可能就是下面這種:
結果大家可能都知道,高斯的經典故事 5050:
如果我想將這個0和100兩個數換掉,那麼就需要改程式碼,寫一個簡單的帶有兩個引數的函式,如下圖:
這樣的函式可能是需要一個數字的開頭,一個數字的結尾,可以稱作一個最簡單的二維度的需求,那麼,這樣一個需求和巢狀函式有什麼關係那?看下面這段程式碼,將累加換成了乘法,但是本質沒有改變:
這是一個巢狀函式,那麼按照上面的邏輯,我在呼叫這個函式的時候給定了一個引數,返回的會是一個函式:
函式名,addInner有沒有!相當於返回的是內部函式,如果換一種寫法來看:
結果是什麼? 執行的結果就是5*6,5*4,這很像我們定義了一個類之後,例項化之後對類內函式進行呼叫的一個過程,首先我們將num1初始化為5,然後返回了一個很類似於c語言中函式指標的玩意兒,實際是內建函式的一個引用,屬於變數,這樣我們利用這個引用再呼叫,那麼num2就被賦值了,整個過程完成。 瞬間感覺這個東西很強大有木有!? 沒有感覺? 那麼再來一些複雜的例子: 第一個:
先解釋一下這段程式碼,這段小程式碼裡面有3個函式,作用是動態擴充套件一個“人”的屬性欄位。 下面兩個函式是驗證函式,第一個函式前加了一句@initMan,有必要解釋一下@,在python中叫做裝飾器,initMan經過修飾以後變成了裝飾函式,經過裝飾函式的修飾,呼叫printManWithDecorate(person)實際上變成了printManWithDecorate = initMan(printManWithDecorate(person),所以,對每個人資訊的列印過程中,呼叫printManWithDecorate與呼叫printMan看起來似乎沒什麼不同,但是實質上是完全不同的,我們先來看一下結果:

如我們所料,兩次呼叫的效果完全不同。 這種場景似乎在哪裡見過?yep,java裡面的裝飾模式即是這種邏輯,沒差,基本完全一樣。這樣的裝飾同樣可以疊加,但是與java不同的是,這種疊加是有順序的,畢竟主體是函式而不是類,但是這種模式更加的精煉與輕量級,並且能夠完成裝飾模式的大多數作用,更加驗證了我之前看到過的一句話:python是一個函式為王的語言。這是一種更加貼近c語言的面向物件的解釋語言。 下期:python類載入