學習Python(2)——函數

來源:互聯網
上載者:User
先寫一個例子——產生n以內的Fibonacci數:

def fib(n):
    a,b=0,1
    while b<n:
        print b,
        a,b=b,a+b

def指出了接下來的部分是一個函數。Python和C語言類似,並不區分過程(無傳回值)和函數(有傳回值)。像上面那樣嚴格的說就是一個過程(Procedure)。
對於一個項目而言,在不同的模組的代碼中插入一段簡潔明了的解說文字是很有必要的。Python支援類似Java-Doc的文法。例如:

def fib(n):
    """Print a Fibonacci series up to n."""
    a,b=0,1
    while b<n:
        print b,
        a,b=b,a+b

將解說文字放在一對“”“(三個又引號)之間,一些文檔產生工具就會將這些文字提取出來,產生HTML或是LaTeX等文檔。寫這些文字費不了多少時間,養成這種習慣絕對是大有好處的。
函數的調用也非常簡單,對於上面的而言,只需直接用fib(100),就會產生相應的輸出:1 1 2 3 5 8 13 21 34 55 89

函數本身也可以被引用。對於已經定義好的fib來說,如果有一句:f=fib,就意味著f引用了fib這個函數。現在這兩個名字所指的就是同一個東西。於是就可以這樣使用:>>>f(100)

輸出結果和上面的是一樣的。可以比照著C語言中的”函數指標“來理解一下。
雖然Python的函數可以不顯式地寫出return語句,實際上這種函數也會返回一個特殊的值None。例如有一個什麼都不乾的函數:

def fun():
    pass

可以通過在解譯器中用print來顯示一下它的值:>>>print fun()
None

現在可以將上面的fib函數改造一下,讓它不再直接產生輸出,而是產生一個Fibonacci數列的List:def fib2(n):
    """Print a Finonacci series up to n."""
    a,b=0,1
    result=[]
    while b<n:
        result.append(b)
        a,b=b,a+b
    return result

append是List類的一個方法,即向一個List後添加元素。這個函數的效果如下:>>>print fib2(100)
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]

預設參數
Python函數支援預設參數。你可以定義一個兩個參數的函數,但在調用的時候可以只告訴其中一個參數或是一個都不告訴——只要你在定義的時候指定了參數的預設值。這很像是從C++中學來的。

def ask_ok(prompt,retries=4,complaint='Yes or no, please!'):
    while True:
        ok=raw_input(prompt)
        if ok in ('y','ye','yes'): return True
        if ok in ('n','no','nop','nope'): return False
        retries=retries-1
        if retries<0: raise IOError, 'refusenik user'
        print complaint

這樣就有了多種調用方式:>>>ask_ok('Do you really want to quit?')
>>>ask_ok('Do you really want to quit?',2)
>>>ask_ok('Do you really want to quilt?',3,'What do you want to do?')

參數的預設值是在定義的時在函數的入口處確定下來的。這可以通過一個實驗來說明:i = 5
def f(arg=i):
    print arg
i = 6
f()

發現輸出的是5而不是6,因為後來的i改變根本不會對函數裡的arg造成影響。
要注意的是,函數的預設參數部分只會被計算一次。這樣如果預設參數是某種複合類型(List,String,Class),可能會產生一種”積累效應“:

def f(a,L=[]):
    L.append(a)
    return L

如果調用三次:>>> print f(1)
[1]
>>> print f(2)
[1, 2]
>>> print f(3)
[1, 2, 3]

要避免這種情況,就需要在定義的參數列表中顯式地將L的預設值指定為None:

def f(a,L=None):
    if L is None:
        L=[]
    L.append(a)
    return L

帶關鍵字的參數
關鍵字可以理解為函數頭部參數的名字。通過在調用函數的時候指定關鍵字,可以不按照參數定義的順序來傳遞參數的值。def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):
    print "-- This parrot wouldn't", action,
    print "if you put", voltage, "volts through it."
    print "-- Lovely plumage, the", type
    print "-- It's", state, "!"

帶關鍵字調用:parrot(1000)
parrot(action = 'VOOOOOM', voltage = 1000000)
parrot('a thousand', state = 'pushing up the daisies')
parrot('a million', 'bereft of life', 'jump')

下面的幾種調用方式是錯的:parrot() # 缺少指定參數
parrot(voltage=5.0, 'dead') # 沒有指出關鍵字
parrot(110, voltage=220) # 傳遞重複參數
parrot(actor='John Cleese') # 不存在的關鍵字

更為靈活的是,可以通過在函數定義時用*name或**name的方式代表不確定的參數或帶有關鍵字的參數(Dictionary)。這個用例子說明會容易理解一下:

def cheeseshop(kind, *arguments, **keywords):
    print "-- Do you have any", kind, '?'
    print "-- I'm sorry, we're all out of", kind
    for arg in arguments: print arg
    print '-'*40
    keys = keywords.keys()
    keys.sort()
    for kw in keys: print kw, ':', keywords[kw]

可以這樣調用:cheeseshop('Limburger', "It's very runny, sir.","It's really very, VERY runny, sir.",client='John Cleese', shopkeeper='Michael Palin',sketch='Cheese Shop Sketch')

結果是:-- Do you have any Limburger ?
-- I'm sorry, we're all out of Limburger
It's very runny, sir.
It's really very, VERY runny, sir.
----------------------------------------
client : John Cleese
shopkeeper : Michael Palin
sketch : Cheese Shop Sketch

傳遞多個參數時還可以通過List來進行。List中的元素會被分離開,稱為Unpack,這是Python解譯器在幕後完成的。例如range函數可以指定兩個參數,可以把這兩個參數構成一個List,再將這個List傳入:>>> args = [3, 6]
>>> range(*args) # call with arguments unpacked from a list

[3, 4, 5]
類似地,可以使用**操作符來傳遞一個字典,對應於帶關鍵字傳遞參數的方式。>>> def parrot(voltage, state='a stiff', action='voom'):
...         print "-- This parrot wouldn't", action,
...         print "if you put", voltage, "volts through it.",
...         print "E's", state, "!"
...
>>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}
>>> parrot(**d)
-- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !

用心領悟一下。

Lambda函數
Python從函數語言中學來了這一功能。Lambda函數是一種匿名函數,功能有些像函數的模板,通過它可能方便地產生其他函數。感覺Lambda函數更加需要領悟,只裡僅僅記幾個例子:>>> def make_incrementor(n):
...         return lambda x: x + n
...
>>> f = make_incrementor(42)
>>> f(0)
42
>>> f(1)
43

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.