Python練習:從入門到實踐——函數

目錄

一、定義函數

1.1 向函數傳遞信息

1.2 實參與形參

二、傳遞實參

2.1 位置實參

2.2  關鍵字實參

2.3 默認值

2.4 等效的函數調用

2.5 避免實參錯誤

三、返回值

3.1 返回簡單值

3.2 實參可選

3.3 返回字典

三、 函數與while結合

四、傳遞列表

4.1 在函數中修改列表

4.2 禁止函數修改列表

練習

五、傳遞任意數量的實參

5.1 結合使用位置實參和任意數量實參

5.2 使用任意數量的關鍵字實參

六、將函數存儲在模塊中

6.1 導入整個模塊

6.2 導入特定的函數

6.3 使用as給函數指定別名

6.4 使用as給模塊指定別名

6.5 導入模塊中的所有函數

七、函數編寫指南


函數是帶名字的代碼塊,用於完成具體的工作

一、定義函數

  • 使用關鍵字 def 定義一個函數 
  • 函數名 (參數1,參數2,參數3...)
  • 調用函數時,指定函數名及所需參數
# 定義函數
def greet_user():
    '''顯示簡單的問候語'''
    print("Hello!")

# 引用函數
greet_user()

1.1 向函數傳遞信息

def greet_user(username):
    """ 顯示簡單的問候語 """
    print("Hello, " + username.title() + "!")

greet_user('gina')

1.2 實參與形參

  • 在greet_user() 函數中,username 是一個形參,指示函數要完成其工作所需要的信息;
  • 調用函數時,'gina'爲實參,實參是調用函數時傳遞給函數的信息

二、傳遞實參

定義函數時,一個函數可能包含多個形參,將實參與形參關聯起來的方式有兩種:

  • 位置實參,要求實參的順序與形參相同
  • 關鍵字實參,每個實參都由變量名和值組成,還可以使用列表和字典

2.1 位置實參

e.g 顯示寵物信息的函數,指出一個寵物屬於哪種動物以及它叫什麼名字。

def describe_pet(animal_type,pet_name):
    """ 顯示寵物信息 """
    print("\nI have a " + animal_type +".")
    print("My " + animal_type +"'s name is " + pet_name.title() + ".")

describe_pet('cat','mona')

位置實參的順序很重要!

2.2  關鍵字實參

關鍵字實參 傳遞給函數一對值,參數名=參數值,因此向函數傳遞實參是無需考慮函數調用中實參的順序。

describe_pet(pet_name='doudou',animal_type='dog')

使用關鍵字實參時,務必準確指出函數定義中的形參名。

2.3 默認值

  • 編寫函數時,可爲每個形參指定默認值
  • 在調用函數時,若爲形參指定了相應的實參值,Python將使用指定的實參值;否則將使用形參的默認值
  • 給形參指定默認值後,可在函數調用中省略相應的實參,因此使用默認值可簡化函數調用
def describe_pet(pet_name,animal_type='dog'):
    """ 顯示寵物信息 """
    print("\nI have a " + animal_type +".")
    print("My " + animal_type +"'s name is " + pet_name.title() + ".")

describe_pet('doudou')
describe_pet('pipi')

# 爲函數提供顯式的實參值 animal_type='cat',Python將忽略默認值
describe_pet('mona','cat')

使用默認值時,在形參列表中必須先列出沒有默認值的形參,再列出有默認值的實參,使得Python可以正確地解讀位置實參。

2.4 等效的函數調用

可以混合使用位置實參、關鍵字實參和默認值。

e.g 

def describe_pet(pet_name,animal_type='dog')
  • 基於此情況:
  • 必須給pet_name提供實參
  • 指定實參時,可以使用位置實參,也可以使用關鍵字實參
  • 如果描述的動物不是dog,必須在函數調用中給animal_type提供實參
describe_pet('doudou')
describe_pet(pet_name='doudou')

describe_pet('mona','cat')
describe_pet(pet_name='mona',animal_type='cat')
describe_pet(animal_type='cat',pet_name='mona')

只要保證函數的輸出時正確的,使用哪種調用方式是無所謂的。

2.5 避免實參錯誤

保證提供的實參數量+默認值=形參數量

三、返回值

  • 可以使用函數處理一些數據並且獲得一個或一組值,函數返回的值稱爲返回值
  • 使用return語句將值返回到調用函數的代碼行

3.1 返回簡單值

return 返回值

def get_formatted_name(first_name,last_name):
    full_name=first_name.title() + ' ' + last_name.title()
    return full_name

print(full_name('gina','li'))

3.2 實參可選

使用默認值將實參變成可選的。

def get_formatted_name(first_name,last_name,middle_name=''):
    if middle_name:
        full_name = first_name.title() +' ' + last_name.title()
    else:
        full_name = first_name.title() + ' ' + middle_name.title()\
                    + ' ' + last_name.title()
    return full_name

musician = get_formatted_name('jimi','hendix')
print(musician)

musician = get_formatted_name('john','hooker','lee')
print(musician)
  • Python將非空字符串解讀爲True
  • 換行符 \

3.3 返回字典

函數可返回任意類型的值,包括列表和字典等較複雜的數據結構。

def build_person(first_name, last_name):
    """" 返回字典,包含一個人的信息 """
    person = {'first': first_name,'last': last_name }
    return person

musician = build_person('jimi','hendrix')
print(musician)

擴展函數,接受可選值。

def build_person(first_name, last_name, age=''):
    """" 返回字典,包含一個人的信息 """
    person = {'first': first_name,'last': last_name }
    if age:
        person['age'] = age
    return person

musician = build_person('jimi','hendrix',27)
print(musician)

三、 函數與while結合

e.g 使用姓和名與用戶打招呼。

def get_formatted_name(first_name, last_name):
    full_name = first_name.title() + ' ' + last_name.title()
    return full_name

while True:
    print("\nPlease tell me your name:")
    print ("enter 'q' at any time to quit)" )
    f_name = input("First name: ")
    if f_name == 'q':
        break

    l_name = input("Last name:")
    if l_name == 'q':
        break

    formatted_name = get_formatted_name(f_name,l_name)
    print("\nHello, " + formatted_name + "!")

四、傳遞列表

e.g 向函數傳遞列表

def greet_users(names):
    for name in names:
        msg = "Hello, " + name.title() + "!"
        print(msg)

usernames = ['jay','juli','margot']
greet_users(usernames)

4.1 在函數中修改列表

在函數中對列表所做的任何修改都是永久性的。

e.g 

def print_models(unprinted_designs,completed_models):
    while unprinted_designs:
        current_design = unprinted_designs.pop()
        print("Printing model: " + current_design)
        completed_models.append(current_design)

def show_compledted_models(completed_models):
    print("\nThe following models have been printed:")
    for completed_modle in completed_models:
        print(completed_modle)

unprinted_designs = ['iphone case','robot pendant','dodecahedron']
completed_modles = []

print_models(unprinted_designs,completed_modles)
show_compledted_models(completed_modles)

4.2 禁止函數修改列表

將列表的副本傳遞給函數。

切片表示 [:] 創建列表的副本。

function_name(list_name[:])

雖然向函數傳遞列表的副本可以保留原始列表的內容,但是除非特殊要求需要傳遞副本,否則還是應將原始列表傳遞給函數,因爲使用現成的原始列表可以避免花時間和內存創建副本,從而提高效率,在處理大型列表是尤其如此。

練習

  1. 創建一個包含魔術師名字的列表,並將其傳遞給一個名爲show_magicians()的函數,這個函數打印列表中每個魔術師的名字;
  2. 編寫一個名爲make_great()的函數,對魔術師列表進行修改,在每個魔術師的名字中都加入字樣“the Great”,調用show_magicians(),確認魔術師列表確實變了;
  3. 在調用make_great()函數時,向其傳遞魔術師列表的副本,不修改原始列表;返回修改後的列表,並將其存儲到另一個列表中,分別使用這兩個列表來調用show_magicians(),確認一個列表包含原始魔術師的名字,另一個列表包含添加了 the great 字樣的魔術師名字。
def show_magicians(magicians):
    for magician in magicians:
        print(magician.title())

def make_great(magicians):
    l = len(magicians)
    for i in range(l):
        magicians[i] = "the Great " + magicians[i]
    return magicians

magicians = ['liu qian','jay chou']

new_magicians = make_great(magicians[:])
show_magicians(magicians)
show_magicians(new_magicians)

五、傳遞任意數量的實參

解決問題:有時,預先不知道函數需要接受多少個實參

處理方式:*形參名

e.g  製作披薩的函數,預先無法確定加入多少配料。(該函數只有一個形參*toppings。)

def make_pizza(*toppings):
    print("\nMaking pizza with the following toppings:")
    for topping in toppings:
        print("-" + topping)

make_pizza('pepperoni')
make_pizza('mushroom','green peppers','extra cheese')
  • 不論函數收到幾個實參,都能處理
  • 形參名*toppings中的“*”讓python創建一個名爲toppings的空元組,並將收到的所有值都封裝到這個元組中

5.1 結合使用位置實參和任意數量實參

如果讓函數接受不同類型的實參,必須在函數定義中將接納任意數量實參的形參放在最後。Python先匹配位置實參和關鍵字實參,再將餘下的實參都收集到最後一個形參中。

# python將收到的第一個值存儲在形參size中,將其他所有值都存儲在元組toppings中。

def make_pizza(size,*toppings):
    print("\nMaking a " + str(size) +
          "-inch pizza with the following toppings:")
    for topping in toppings:
        print("-" + topping)

# 在函數調用中,首先指定表示比薩尺寸的實參,然後根據需要指定任意數量的配料。
make_pizza(12,'pepperoni')
make_pizza(16,'mushroom','green peppers','extra cheese')

5.2 使用任意數量的關鍵字實參

有時,需要接受任意數量的實參,但是預先不知道傳遞給函數的會是什麼信息,

在這種情況下可將函數編寫成可接受任意數量的“鍵—值對”——調用語句提供了多少就接受多少。

e.g 創建用戶簡介:你將收到有關用戶的信息,但不確定會是什麼樣的信息。build_profile()接受名和姓,同時還接受任意數量的關鍵字實參。

def build_profile(first, last, **user_info):
    """ 創建一個字典,其中包含我們知道的有關用戶的一切 """
    profile = {}
    profile['first_name'] = first
    profile['last_name'] = last
    for key, value in user_info.items():
        profile[key] = value
    return profile

user_profile = build_profile('albert','einstein',location='princeton',field='physics')
print(user_profile)
  • build_profile() 的定義要求用戶必須提供姓和名,同時允許用戶根據需要提供任意數量的“值對”;
  • 形參**user_info中兩個星號讓python創建一個名爲user_info的空字典,並將收到的所有名稱——值對,都封裝到這個字典中;
  • 在這個函數中,可以像訪問其他字典一樣訪問user_info中的鍵值對。

六、將函數存儲在模塊中

  • 函數的優點之一是,使用函數可將代碼塊與主程序分離,通過給函數指定描述性名稱,可讓主程序容易理解得多;
  • 更進一步,可將函數存儲在被稱爲模塊的獨立文件中,再將模塊導入到主程序中;
  • import 語句允許在當前運行的程序文件中使用模塊中的代碼

6.1 導入整個模塊

模塊是擴展名爲.py的文件,包含要導入程序中的代碼。

e.g 創建一個包含函數make_pizza() 的模塊。

pizza.py

def make_pizza(size,*toppings):
    print("\nMaking a " + str(size) +
          "-inch pizza with the following toppings:")
    for topping in toppings:
        print("-" + topping)

在pizza.py所在的目錄創建另一個名爲making_pizza.py的文件,在這個文件中導入創建的模塊pizza.py,並調用函數make_pizza()兩次

import pizza
pizza.make_pizza(12,'pepperoni')
pizza.make_pizza(16,'mushroom','green peppers','extra cheese')

import pizza 讓python打開文件pizza.py,並將其中的所有函數都複製到這個程序中,進而在making_pizza中可以使用pizza中定義的所有函數。

# 導入模塊
import module_name

# 調用模塊中的函數
module_name.function_name()

6.2 導入特定的函數

from module_name import function_name

使用逗號,分隔函數名,可根據需要從模塊中導入任意數量的函數

from module_name import function_name0,function_name1,function_name2

使用這種語法調用函數時,無需使用句點。

6.3 使用as給函數指定別名

若要導入的函數名稱與程序中現有的名稱衝突,或函數名稱太長,可以指定簡短且獨一無二的別名。

e.g 

from pizza import making_pizza as mp

mp(16,'pepperoni')

6.4 使用as給模塊指定別名

import pizza as p
p.making_pizza(12,'pepperoni')

6.5 導入模塊中的所有函數

使用運算符(*)導入模塊中的所有函數

from module_name import *

七、函數編寫指南

  • 應給函數指定描述性名稱,且只在其中使用小寫字母和下劃線,爲模塊命名時也應遵循此規則,描述性名稱可幫助別人明白代碼的作用;
  • 每個函數都應包含簡要的註釋,註釋緊跟在函數定義之後,(知道函數的名稱、需要的實參、返回值的類型,就能在自己的程序中使用它)
  • 給形參指定默認值時,等號兩邊不要有空格
def function_name(parameter_0,parameter_1='default value')
  • 函數調用中的關鍵字實參,等號兩邊也不要有空格
function_name(value_0,parameter_1='value')
  • 如果程序或模塊中包含多個函數,可使用兩個空行將相鄰的函數分割開,以便知道上一個函數何時結束,下一個函數何時開始
  • 所有的import語句都應放在文件開頭

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章