1. 程式人生 > >Python3 基礎:定義函式

Python3 基礎:定義函式

在Python中,定義一個函式要使用def語句,依次寫出函式名、括號、括號中的引數和冒號:,然後,在縮排塊中編寫函式體,函式的返回值用return語句返回

如果沒有return語句,函式執行完畢後也會返回結果,只是結果為None。
return None可以簡寫為return。

1.空函式

如果想定義一個什麼事也不做的空函式,可以用pass語句

def nop():
    pass

pass語句什麼都不做,那有什麼用?實際上pass可以用來作為佔位符,比如現在還沒想好怎麼寫函式的程式碼,就可以先放一個pass,讓程式碼能執行起來。

pass還可以用在其他語句裡,比如:

if age >= 18:
pass
缺少了pass,程式碼執行就會有語法錯誤。

2.引數檢查

def my_abs(x):
if not isinstance(x, (int, float)):
    raise TypeError('bad operand type')
if x >= 0:
    return x
else:
    return -x

3.返回多個值

import math

def move(x, y, step, angle=0):
    nx = x + step * math.cos(angle)
    ny = y - step * math.sin(angle)
    return nx, ny

>>> x, y = move(100, 100, 60, math.pi / 6)
>>> 151.96152422706632 70.0

其實,Python函式返回的仍然是單一值:

>>> r = move(100, 100, 60, math.pi / 6)
>>> print(r)
(151.96152422706632, 70.0)

原來返回值是一個tuple!但是,在語法上,返回一個tuple可以省略括號,而多個變數可以同時接收一個tuple,按位置賦給對應的值,所以,Python的函式返回多值其實就是返回一個tuple.

4.函式的引數

  1. 位置引數:就是定義函式的引數
  2. 預設引數:在定義時給引數賦一個預設值

     # 計算x的n次方
     def power(x, n=2):
        s = 1
        while n > 0:
            n = n - 1
            s = s * x
        return s
    

    定義預設引數要牢記一點:預設引數必須指向不變物件![預設引數的坑,請看文章末尾]

  3. 可變引數: *numbers, 可變引數允許你傳入0個或任意個引數

    def calc(*numbers):
        sum = 0
        for n in numbers:
            sum = sum + n * n
        return sum
    
    # 傳入已經存在的list,使用    *list變數名稱
    >>> nums = [1, 2, 3]
    >>> calc(*nums)
    14
    

    在函式內部,引數numbers接收到的是一個tuple.

  4. 關鍵字引數:
    可變引數允許你傳入0個或任意個引數,這些可變引數在函式呼叫時自動組裝為一個tuple。而關鍵字引數允許你傳入0個或任意個含引數名的引數,這些關鍵字引數在函式內部自動組裝為一個dict。

    def person(name, age, **kw):
        print('name:', name, 'age:', age, 'other:', kw)
    
    # 呼叫person函式
    >>> person('Bob', 35, city='Beijing')
    name: Bob age: 35 other: {'city': 'Beijing'}
    >>> person('Adam', 45, gender='M', job='Engineer')
    name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'}
    
    # 現成的dict使用   **dict名稱  
    >>> extra = {'city': 'Beijing', 'job': 'Engineer'}
    >>> person('Jack', 24, **extra)
    name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}
    
    **extra表示把extra這個dict的所有key-value用關鍵字引數傳入到函式的**kw引數,kw將獲得一個dict,注意kw獲得的dict是extra的一份拷貝,對kw的改動不會影響到函式外的extra。
    
  5. 命名關鍵字引數:

    如果要限制關鍵字引數的名字,就可以用命名關鍵字引數,例如,只接收city和job作為關鍵字引數。這種方式定義的函式如下:

    def person(name, age, *, city, job):
        print(name, age, city, job)
    

    命名關鍵字引數需要一個特殊分隔符*,*後面的引數被視為命名關鍵字引數。
    呼叫方式如下:

    >>> person('Jack', 24, city='Beijing', job='Engineer')
    Jack 24 Beijing Engineer
    

    如果函式定義中已經有了一個可變引數,後面跟著的命名關鍵字引數就不再需要一個特殊分隔符*了:

    def person(name, age, *args, city, job):
        print(name, age, args, city, job)
    

    命名關鍵字引數必須傳入引數名,這和位置引數不同。如果沒有傳入引數名,呼叫將報錯.
    命名關鍵字引數可以有預設值,從而簡化呼叫

    def person(name, age, *, city='Beijing', job):
        print(name, age, city, job)
    
    # 由於命名關鍵字引數city具有預設值,呼叫時,可不傳入city引數:
    >>> person('Jack', 24, job='Engineer')
    Jack 24 Beijing Engineer
    
  6. 引數組合:
    在Python中定義函式,可以用必選引數、預設引數、可變引數、關鍵字引數和命名關鍵字引數,這5種引數都可以組合使用。但是請注意,引數定義的順序必須是:必選引數、預設引數、可變引數、命名關鍵字引數和關鍵字引數。

預設引數的坑

先定義一個函式,傳入一個list,新增一個END再返回:

def add_end(L=[]):
    L.append('END')
    return L

這個函式正常呼叫是沒有問題的,但是如果你這樣:

>>> add_end()
['END', 'END']
>>> add_end()
['END', 'END', 'END']

為什麼會這樣呢?
Python函式在定義的時候,預設引數L的值就被計算出來了,即[],因為預設引數L也是一個變數,它指向物件[],每次呼叫該函式,如果改變了L的內容,則下次呼叫時,預設引數的內容就變了,不再是函式定義時的[]了。

所以,定義預設引數要牢記一點:預設引數必須指向不變物件!

幾個實用函式

函式 描述
dir([obj]) —顯示物件的屬性,如果沒有提供引數, 則顯示全域性變數的名字
help([obj])— 以一種整齊美觀的形式 顯示物件的文件字串, 如果沒有提供任何引數, 則會進入互動式幫助。
int(obj) —將一個物件轉換為整數
len(obj) —返回物件的長度
open(fn, mode)— 以 mode(‘r’ = 讀, ‘w’= 寫)方式開啟一個檔名為 fn 的檔案
range([[start,]stop[,step])— 返回一個整數列表。起始值為 start, 結束值為 stop - 1; start預設值為 0, step預設值為1。
raw_input(str)— 等待使用者輸入一個字串, 可以提供一個可選的引數 str 用作提示資訊。
str(obj)— 將一個物件轉換為字串
type(obj)— 返回物件的型別(返回值本身是一個type 物件!)