標籤:python
Python的函數可以返回一個值或者對象。若無傳回值,預設返回None。若返回多個對象,實際返回一個元組。
函數是通過賦值(對象引用)傳遞的。調用者以及函數通過引用共用對象,但是不需要別名。改變函數中的參數名並不會改變調用者中的變數名,但是改變傳遞的可變對象可以改變調用者共用的那個對象。
函數名是一個對象的引用,可以自由地把這個對象賦給其他的名稱並且通過任何引用調用它。
變數範圍:
函數定義了本地範圍,而模組定義的是全域範圍。變數分別對應三種不同的範圍:
1、若一個變數在def內賦值,它被定位在這個函數內。
2、若一個變數在一個嵌套的def中賦值,對於嵌套的函數,它是非本地的
3、若在def外賦值,它就是整個檔案全域的。
如果需要給一個在函數內部卻位於模組檔案頂層的變數名賦值,需要在函數內部通過global語句聲明。注意在原處改變對象並不會把變數劃分為本地變數,實際上只有對變數名賦值才可以。例如L在頂層被賦值為一個列表,在函數內部像L.append(x)並不會將L劃分為本地變數,而L=x卻可以。記住:修改一個對象並不是對一個名稱賦值。
在函數內對變數名賦值將會將其劃分為本地變數,本地變數在引用前需定義!!!
變數名引用分為三個範圍進行尋找:首先是本地,之後是函數內,之後全域,最後是內建。(LEGB)
當在函數中給一個變數名賦值時(而不是在一個運算式中對其進行引用),Python總是建立或改變本地範圍的變數名,除非它已經在那個函數中聲明為全域變數。
lambda:Python允許用lambda關鍵字創造匿名函數,用合適的運算式(而非語句)調用lambda產生一個可以像其他函數一樣使用的函數對象。lambda運算式引入了新的本地範圍。
在一個函數內定義一個函數被稱為閉包。如果在一個內建函式裡,對在外部範圍(但不是在全域範圍)的變數進行引用,那麼內建函式就被認為是閉包。定義在外部函數內的但由內建函式引用或者使用的變數被稱為自由變數。eg:
def maker(N):
def action(X):
return X ** N
return action
f=maker(2) #f : <function action at ....>
f(3) #9
#外部函數maker產生並返回了一個嵌套的函數,卻並不調用這個內嵌的函數。內嵌的函數記住了N的值。
#實際上,本地範圍內的N作為狀態資訊被保留下來
也可以用類來替代閉包。
函數參數:
func(value)
|
調用者
|
常規參數:通過位置進行匹配
|
func(name=value)
|
調用者
|
關鍵字參數:通過變數名匹配
|
func(*seq)
|
調用者
|
傳遞所有對象,並作為獨立的基於位置的參數(解包)
|
func(**dict)
|
調用者
|
成對的傳遞所有關鍵字/值,並作為獨立的關鍵字參數(解包)
|
def func(name)
|
函數
|
常規參數:通過位置或變數名匹配
|
def func(name=value)
|
函數
|
預設參數 |
def func(*name)
|
函數
|
匹配並收集所有包含位置的參數,並作為元組傳遞給函數(收集)
|
def func(**name)
|
函數
|
匹配並收集所有包含位置的參數,並作為字典傳遞給函數(收集)
|
Python中允許的函數調用的完整語句為:
func(value,name=value,*seq,**dict)
函數定義頭部的完整語句為:
def func(name,name=value,*name,**name)
關於A函數調用B函數,兩者的聲明順序:B函數無論是在A函數之前聲明還是在之後聲明都可以,只要保證調用A函數的語句在B函數的聲明之後就可以。
函數屬性:在函數外可以向函數附加使用者定義的屬性。eg:函數func,func.count=0。像count這種變數的名稱對於一個函數來說是本地的,但是,其值在函數退出後仍然保留。
內建函數:
apply(func[,nkw][,kw]):用可選的參數來調用func,nkw為非關鍵字函數,kw為關鍵字函數;傳回值是函數調用的傳回值。
filter(func,seq):調用一個布爾函數來迭代遍曆每個seq中的元素;返回一個使函數傳回值為True的元素的序列。
map(func,seq1[,seq2...]):將函數作用於給定序列的每個元素,並用一個列表來提供傳回值;若func為None,func表現為一個身份函數,返回一個含有每個序列中元素集合的n個元組的列表(同zip)。
reduce(func,seq[,int]):將二元函數作用於seq序列的元素,每次攜帶一對(先前的結果以及下一個序列元素)連續地將現有的結果和下一個值作用在獲得的隨後的結果上,最後減少我們的序列為一個單一的傳回值;如果初始值init給定,第一個比較會是init和第一個序列元素而不是序列的頭兩個元素。
偏函數應用:固化第一個參數為固定參數,並返回另一個帶n-1個參數函數對象。
from operator import add
from functools import partial
add1=partial(add,1) #add1(x)==add(1,x)
使用偏函數時注意關鍵字參數。
Python是靜態檢測Python的本地變數,當編譯def代碼時,不是通過發現指派陳述式在運行時進行檢測的。也就是說,在函數中一旦發現指派陳述式就將其變數視為本地變數,即使賦值在引用之後。(如果賦值在引用之後,若無global聲明,則引用會報錯)
本文出自 “蓮的思念” 部落格,請務必保留此出處http://liandesinian.blog.51cto.com/7737219/1545103
函數和函數式編程