> 相信大家學習過其他語言,懂得函數的作用。簡單的說函數最好的作用就是可以使程序變得懶惰。python作為后起之秀,當然也會擁有函數這個有用的東西;
### 創建函數
使用def語句即可創建函數,如創建一個用來生成指定邊界的斐波那契數列的函數:
~~~
#!/usr/bin/env python3
def fib(n):#使fibonacci數列到達n
'打印fibonacci數列到n'
a,b=0,1
while a<n:
print(a,end=' ')
a,b=b,a+b
fib(20)
0 1 1 2 3 5 8 13
~~~
關鍵字 def 引入了一個函數 定義 。在其后必須跟有函數名和包括形式參數的圓括號。函數體語句從下一行開始,必須是縮進的。
### 有關事項詳解:
### 文檔化函數
函數體的第一行語句可以是可選的字符串文本,這個字符串是函數的文檔字符串,或者稱為 docstring 。使用如下方式可以查看:
~~~
print(fib.__doc__)
打印fibonacci數列到n
~~~
### 參數的傳遞
函數 調用 會為函數局部變量生成一個新的符號表。 確切的說,所有函數中的變量賦值都是將值存儲在局部符號表。 變量引用首先在局部符號表中查找,然后是包含函數的
局部符號表,然后是全局符號表,最后是內置名字表。 因此,全局變量不能在函數中直接賦值(除非用 global 語句命名),盡管他們可以被引用。
函數引用的實際參數在函數調用時引入局部符號表,因此,實參總是 傳值調用 (這里的 值 總是一個對象 引用 ,而不是該對象的值)。 1 一個函數被另一個函數調用時,
一個新的局部符號表在調用過程中被創建。
### 函數名可以賦予其他名字
函數名可以重命名:
~~~
f=fib
f(100)
0 1 1 2 3 5 8 13 21 34 55 89
~~~
可能有人誤會說fib()函數沒有返回值,千萬注意這里使用的是函數名,沒有使用函數調用;事實上fib()確實返回了一個空值,未加return語句返回的時None;可以使用下方法查看:
~~~
print(fib(10))
0 1 1 2 3 5 8 None
~~~
### 深入理解python3函數定義
在python中,你也可以定義包含若干參數的函數,這里有三種可用的形式,可以混合使用:
### 默認參數值:
默認參數的定義方法如下:
~~~
def f(a,b,x=3,y=5):
'測試默認參數'
print(a,b,x,y)
~~~
上面的函數中參數a和b是必要參數,而參數x和y是可選參數,有自己的默認值;
這個函數可以通過幾種不同的方式調用:
只給出必要參數: f(1,2)
給出一個可選的參數: f(1,2,4)
給出所有參數: f(1,2,4,6)
注意:
默認值只被賦值一次。這使得當默認值是可變對象時會有所不同,比如列表、字典或者大多數類的實例。例如,下面的函數在后續調用過程中會累積(前面)
傳給它的參數:
~~~
def f(a, L=[]):
L.append(a)
return L
print(f(1))
print(f(2))
print(f(3))
#輸出
[1]
[1, 2]
[1, 2, 3]
~~~
如果你不想讓默認值在后續調用中累積,你可以像下面一樣定義函數:
~~~
def f(a, L=None):
if L is None:
L = []
L.append(a)
return L
~~~
### 關鍵字參數:
有些時候函數的參數順序是很難記憶的,為了讓事情簡單些,可以在調用時提供參數的名字:
~~~
def f(a,b,x=3,y=5):
'測試關鍵字參數'
print(a,b,x,y)
#普通調用
f(1,2)
#關鍵字調用
f(a=1,b=2,y=6)
f(1,2,y=3)
#輸出
1 2 3 5
1 2 3 6
1 2 3 3
~~~
注意:當使用了關鍵字后必須一直使用不然會報錯:
比如下:
f(a=1,2)
SyntaxError: non-keyword arg after keyword arg
### 可變參數列表:
可以讓函數調用可變個數的參數,這些參數被包裝進一個元組或者字典。
可變參數定義方式:只需在參數前面加上×號,參數被包裝在元祖中
~~~
def print_params(title,*params):
print(title)
print(params)
~~~
可以和普通參數聯合使用,×號收集的時其余的位置參數如: print_params(“peace”,23,170) 。如果不提供任何收集的元素,params時個空元祖:() 如: print_params(“pp”)
同樣還可以處理關鍵字參數,定義如下:只需在關鍵字參數前面加上××號,被包裝在字典中;
~~~
def print_params(title,**params):
print(title)
print(params)
~~~
調用時必須注明關鍵字參數。可以這樣調用:
print_params(“peace”,age=23,high=170)
print_params(“pp”)
### 參數列表的分拆
與可變參數剛好相反,
當你要傳遞的參數已經是一個列表,但要調用的函數卻接受分開一個個的參數值。這時候你要把已有的列表拆開來
你可以在調用時加一個×操作符來自動把參數列表拆開:比如range():
~~~
>>> list(range(1,10))
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> args=[1,10]
>>> list(range(*args))
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>
~~~
以同樣的方式,可以使用 **操作符分拆關鍵字參數為字典:
### Lambda 形 式
出于實際需要,有幾種通常在函數式編程語言例如 Lisp 中出現的功能加入到了 Python。通過 lambda 關鍵字,可以創建短小的匿名函數。這里有一個函數返回它的兩個參數的和: lambda a, b: a+b 。 Lambda 形式可以用于任何需要的函數對象。出于語法限制,它們只能有一個單獨的表達式。語義上講,它們只是普通函數定義中的一個語法技巧。類似于嵌套函數定義,lambda 形式可以從外部作用域引用變量:
~~~
def fun(n):
'下面x是參數,x+n是返回值'
return lambda x: x+n
#f接收lambda返回的函數
f=fun(10)
print(f(0))
print(f(10))
#輸出:
10
20
~~~
#### 相關鏈接:
[python3入門之類](http://rlovep.com/2015/09/23/python3%E5%85%A5%E9%97%A8%E4%B9%8B%E7%B1%BB/)
[python3入門之函數](http://rlovep.com/2015/09/06/python3%E5%85%A5%E9%97%A8%E4%B9%8B%E5%87%BD%E6%95%B0/)
[python3入門之循環](http://rlovep.com/2015/09/06/python3%E5%85%A5%E9%97%A8%E4%B9%8B%E5%BE%AA%E7%8E%AF/)
[python3之if語句](http://rlovep.com/2015/08/05/python3%E4%B9%8Bif%E8%AF%AD%E5%8F%A5/)
[python3入門之賦值語句介紹](http://rlovep.com/2015/08/03/python3%E5%85%A5%E9%97%A8%E4%B9%8B%E8%B5%8B%E5%80%BC%E8%AF%AD%E5%8F%A5%E4%BB%8B%E7%BB%8D/)
[python3入門之print,import,input介紹](http://rlovep.com/2015/08/03/python3%E5%85%A5%E9%97%A8%E4%B9%8Bprint%EF%BC%8Cimport%EF%BC%8Cinput%E4%BB%8B%E7%BB%8D/)
[python3入門之set](http://www.cnblogs.com/onepeace/p/4791578.html)
[python3入門之字典](http://rlovep.com/2015/07/29/python3%E5%85%A5%E9%97%A8%E4%B9%8B%E5%AD%97%E5%85%B8/)
[python3入門之字符串](http://rlovep.com/2015/07/28/python%E5%85%A5%E9%97%A8%E4%B9%8B%E5%AD%97%E7%AC%A6%E4%B8%B2/)
[python3入門之列表和元組](http://rlovep.com/2015/07/14/python%E5%85%A5%E9%97%A8%E4%B9%8B%E5%88%97%E8%A1%A8%E5%92%8C%E5%85%83%E7%BB%84/)
[python3入門之軟件安裝](http://rlovep.com/2015/07/14/python%E5%85%A5%E9%97%A8%E4%B9%8B%E8%BD%AF%E4%BB%B6%E5%AE%89%E8%A3%85/)
[python3爬蟲之入門和正則表達式](http://rlovep.com/2015/09/23/python3%E7%88%AC%E8%99%AB%E4%B9%8B%E5%85%A5%E9%97%A8%E5%92%8C%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/)