本文會介紹如何將語句組織成函式,還會詳細介紹引數和作用域的概念,以及遞迴的概念及其在程式中的用途。
一. 建立函式
函式是可以呼叫,它執行某種行為並且返回乙個值。用def語句即可定義乙個函式:(並非所有的函式都會返回一些東西)
deffibs(num):
result = [0,1]
for i in range(num-2):
return result
記錄函式
如果想給函式寫文件以便讓人理解的話,可以加入注釋(以#開頭)。另乙個方式就是直接寫上字串,它會作為函式的一部分進行儲存,這成為文件字串。
defsquare(x):
'計算x的平方
'return x*x
#文件字串可以按如下方式訪問:
>>>square._doc_
'計算x的平方
'
二. 引數魔法
函式使用起來很簡單,建立起來也不複雜,但是函式引數的用法有時就不可思議了。
2.1 我能改變引數嗎
在函式內為引數賦予新值,不會改變外部任何變數的值:
>>> defto_change(n):
n = 's'
>>> name = 'b'
>>>to_change(name)
>>>name'b
'
字串(以及數字和元組)是不可變的,即無法被修改。但是如果將可變的資料結構如列表用作引數時,引數就會被改變了。
>>> defchange(n):
n[0] = 'ss'
>>> names = ['
aa','zz'
]>>>change(names)
>>>names['
ss', '
zz']
2.2 關鍵字引數和預設值
目前為止,我們所使用的引數都叫做位置引數。有時候引數順序是很難記住的,為了讓事情簡單些,可以提供引數的名字:
>>> def hello(greeting,name):print '%s,%name!'
>>> hello(greeting = '
hello
',name = '
world')
hello,world!
這樣一來,引數順序就完全沒影響了,但是引數名和值一定要對應。
這樣使用引數名提供的引數叫做關鍵字引數,主要作用在於可以明確每個引數的作用。
關鍵字引數最厲害的地方在於可以在函式中給引數提供預設值:
>>> def hello(greeting = 'hello
',name = '
world'):
'%s,%name!
'
當引數具有預設值時,呼叫的時候就不用提供引數了,可以不提供,提供一些或提供所有的引數。
>>>hello()'hello,world!
'>>> hello('
greeting')
'greeting,world!
'>>> hello(name = '
universe')
'hello,universe!
'
2.3 收集引數
如果函式中能儲存多個名字就好了,使用者可以給函式提供任意多的引數,我們需要這樣做:定義函式時提供乙個引數,在前面加個星號。
>>> def print_para(*paras):paras
>>> print_para('ss'
)('ss
',)>>> print_para(1,2,3)
(1, 2, 3)
引數前的星號將所有值放置在同乙個元組中,可以說是將這些「其餘位置的引數」收集起來再使用。如果不提供任何收集元素,引數得到的是乙個空元組()。
但是如果需要處理關鍵字引數的「收集」操作,我們需要2個星號「**」:
>>> def print_params(x,y,z=3,*pospar,**keypar):x,y,z
pospar
keypar
>>> print_params(1,2,3,5,6,7,foo=1,bar=2)
1 2 3(5, 6, 7)
>>> print_params(1,2)
1 2 3()
{}
請仔細體味上面的例子,前三個引數是固定的,第四個引數pospar是位置引數,可以收集多個引數,第五個引數是關鍵字引數,可以收集多個關鍵字引數。當沒有輸入時,預設為空元組或者空字典。
2.4 反轉過程
剛剛已經討論過如何將引數收集為元組和字典了,如果使用*和**的話,還可以執行相反的操作。(1)在呼叫的時候使用
>>> defadd(x,y):
return x+y
>>> params =(1,2)
>>> add(*params)
3
(2)在定義的時候使用
>>> def with_stars(**kds):print kds['
name
'],'
is',kds['
age'],'
years old
'>>> args =
>>> with_stars(**args)
mr.gumby
is 42 years old
三. 作用域
在執行x=1賦值語句後,名稱x引用到值1。這就像用字典一樣,鍵引用值,當然,變數和所對應的值用的是個『不可見』的字典。內建vars函式可以返回這個字典:
>>> x=1>>> scope =vars()
>>> scope['x'
]1>>> scope['
x'] += 1
>>>x
2
這個不可見的字典叫做命名空間或者作用域。除了全域性作用域外,每個函式呼叫都會建立乙個新的作用域。
一般學過程式設計的基本都知道什麼是作用域了,這裡就不細講了。
四. 遞迴
遞迴的定義包括它們自身定義內容的引用。
乙個有用的遞迴函式包含以下幾部分:
(1)當函式直接返回值時有基本例項(最小可能性問題)
(2)遞迴例項,包括乙個或者多個問題最小部分的遞迴呼叫。
這裡的關鍵是將問題分解為小部分,遞迴不能永遠繼續下去,因為它總是以最小可能性問題結束,而這些問題又儲存在基本例項中。
下面我們來看3個經典的遞迴例子:
a.階乘
>>> deffactorial(n):
if n == 1:
return 1
else
:
return n * factorial(n-1)
b.冪
>>> defpower(x,n):
if n ==0:
return 1
else
:
return x * power(x,n-1)
c.二元查詢(假設number必然在序列sequence中)
>>> defsearch(sequence,number,lower,upper):
if lower ==upper:
assert num ==sequence[upper]
return
upper
else
: middle = (lower+upper) // 2
if number >sequence[middle]:
return search(sequence,number,middle+1,upper)
else
:
return search(sequence,number,lower,middle)
python學習筆記之(五)
高階函式 高階函式 higher order function 可接受函式作為引數,也可以把函式作為返回值。map reduce map 接受兩個引數,乙個是函式,乙個是數列。map將傳入的函式一次作用在數列的每個元素上,將結果作為新的list返回。def f x return x x map f,...
Python學習筆記 抽象
物件導向 物件 例項 由資料及其能對其實施的操作所構成的封裝體。類 描述了物件的特徵 資料和操作 類的定義 class classname object define classname class class suite 類的方法 class dog object def greet self p...
Python學習之抽象
1.python可以為函式指定別名,import math y math.sqrt callable y true 判斷是否可呼叫,即是否是函式 2.函式與條件語句以及迴圈語句一樣,也是通過縮進來識別,不同的是,由於函式用於重複呼叫,所以需要為其指定乙個別名,乙個標號 def hello name ...