天天看點

小菜鳥的python學習之路(7)學習階梯

學習階梯

《Python程式設計:從入門到實踐》

  • 第一部分:基礎知識

第8章 函數

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

  1. 定義函數

greeter.py

def greet_user():
    """顯示簡單的問候語"""
    print("Hello!")
    
greet_user()
           

函數定義關鍵字是def, 定義以冒号結尾

緊跟的冒号後的所有 縮進行 構成了函數體

“”"括起來的是文檔字元串的注釋,描述了函數是做什麼的,python可以用他們來生成有關程式中函數的文檔。

調用函數,指定函數名及其括号内的必要資訊即可,作用是讓python執行函數内的代碼。

  • 向函數傳遞資訊

可在函數定義的括号内添加變量名,添加變量名可讓函數接受給這個變量名指定的任何值。

def greet_user(username):
    """顯示簡單問候語"""
    print("Hello, "+username.title()+"!")
    
greet_user('jesse')
           
  • 實參和形參

形參:在函數定義中,函數()内的變量名是形參,是函數完成其工作所需的一項資訊

實參:在調用函數時,括号内的值’jesse’就是一個實參,實參是調用函數時傳遞給函數的參數

舉個栗子:簡單來說,就是有個會場,會場内的某個座位被我們貼上了“特殊嘉賓”,這個座位就是專門給特殊嘉賓做的,誰是特殊嘉賓呢? 任何人隻要被你允許做到那個座位上,那這個人就是特殊嘉賓。

這裡 “特殊嘉賓” 就是函數定義的變量名,“被允許做到那個位置上的人”就是你調用函數時傳遞的參數,也就是實際的參數,實參。

練習

#8-1 消息:編寫一個名為 display_message()的函數,它列印一個句子,指出你在本章學的是什麼。調用這個函數,确認顯示的消息正确無誤。
def display_message():
    print("\nYou learn about functions in this chapter.")
display_message()
           
#8-2 喜歡的圖書:編寫一個名為 favorite_book()的函數,其中包含一個名為 title的形參。這個函數列印一條消息,如 One of my favorite books is Alice in Wonderland。調用這個函數,并将一本圖書的名稱作為實參傳遞給它。
def favorite_book(title):
    print("One of my favorite books is "+title)
favorite_book('Alice in Wonderland')
           
  1. 傳遞實參

函數定義中可能包含多個形參,是以函數調用中也可能包含多個實參。

位置實參:要求實參的順序和形參的順序相同;

關鍵字實參:每個實參都由變量名和值組成;

還可使用清單和字典;

  • 位置實參

可根據需要調用函數任意次

調用函數多次是一種效率極高的工作方式

根據需要使用任意數量的位置實參

位置實參的順序很重要

pets.py

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('hamster','harry')
#調用函數多次
describe_pet('dog','willie')
#位置實參的順序很重要
describe_pet('willie','dog')
           
  • 關鍵字實參

關鍵字實參是傳遞給函數的名稱-值對

無需考慮調用中的實參順序,還清楚地指出函數調用中各個值的用途

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(animal_type='hamster',pet_name='harry')
           

關鍵字實參的順序無關緊要,因為python知道各個值該存儲到哪個形參中。

  • 預設值

編寫函數時,可給每個形參指定預設值。

給形參提供了實參時,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(pet_name='wille')
           

在這個函數的定義中,修改了形參的排列順序

因為一個形參被指定了預設值,,無需實參指定動物類型。

  • 等效的函數調用

由于可混合使用位置實、關鍵字實參和預設值,通常有多種等效的函數調用方式

def describe_pet(pet_name,animal_type='dog'):
    print("My " + animal_type + "'s name is " + pet_name.title() + ".")
    
#一條名為willie的小狗
describe_pet('willie')
describe_pet(pet_name='willie')
    
#一隻名為Harry的倉鼠
describe_pet('harry','hamster')
describe_pet(pet_name='harry',animal_type='hamster')
describe_pet(animal_type='hamster',pet_name='harry')
           
  • 避免實參錯誤

提供的實參多于或少于函數完成其工作所需的資訊時,将出現實參不比對錯誤。

#這裡程式會報錯,調用函數沒有指定任何實參
def describe_pet(pet_name,animal_type='dog'):
    print("My " + animal_type + "'s name is " + pet_name.title() + ".")
    
describe_pet()
           

練習

#8-3 T 恤:編寫一個名為 make_shirt()的函數,它接受一個尺碼以及要印到 T 恤上的字樣。這個函數應列印一個句子,概要地說明 T 恤的尺碼和字樣。使用位置實參調用這個函數來制作一件 T 恤;再使用關鍵字實參來調用這個函數。
def make_shirt(size,words):
    print("The size of this T-shirt is "+size+" and the words are "+words+".")
make_shirt(size='L',words='made in China')
           
#8-4 大号 T 恤:修改函數 make_shirt(),使其在預設情況下制作一件印有字樣“I love Python”的大号 T 恤。調用這個函數來制作如下 T 恤:一件印有預設字樣的大号 T 恤、一件印有預設字樣的中号 T 恤和一件印有其他字樣的 T 恤(尺碼無關緊要)。
def make_shirt(size='大号',words='I love Python'):
    print("\nT-shirt:")
    print("\tsize: "+size)
    print("\twords: "+words)
make_shirt()
make_shirt(size='中号')
make_shirt(words='其它字樣')
make_shirt(size='小号',words='else')
           
#8-5 城市:編寫一個名為 describe_city()的函數,它接受一座城市的名字以及該城市所屬的國家。這個函數應列印一個簡單的句子,如 Reykjavik is in Iceland。給用于存儲國家的形參指定預設值。為三座不同的城市調用這個函數,且其中至少有一座城市不屬于預設國家。
def describe_city(city_name,city_country='Iceland'):
    print(city_name.title()+" is in "+city_country.title()+".")
describe_city(city_name='reykjavik')
describe_city(city_name='reykjavik', city_country='sydney')
describe_city(city_name='london',city_country='england')
           
  1. 傳回值

函數并非總是直接顯示輸出,可以處理一些資料,并傳回一個或一組值。

可使用return語句将值傳回到調用函數的代碼行

  • 傳回簡單值

formatted_name.py

def get_formatted_name(first_name,last_name):
    """傳回整潔的姓名"""
    full_name = first_name+' '+last_name
    return full_name.title()
musician=get_formatted_name('jimi','hendrix')
print(musician)
           

函數傳回結果到函數調用行

調用傳回值的函數時,需要提供一個變量,用于存儲傳回的值

  • 讓實參變成可選的
#改變前
def get_formatted_name(first_name,middle_name,last_name):
    """傳回整潔的姓名"""
    full_name =first_name+' '+middle_name+' '+last_name
    return full_name.title()

musician=get_formatted_name('john','lee','hooker')
print(musician)
           
#改變後
def get_formatted_name(first_name, last_name, middle_name=''):
    """傳回整潔的姓名"""
    if middle_name:
        full_name=first_name+' '+middle_name + ' ' + last_name
    else:
        full_name = first_name + ' ' + last_name
    return full_name.title()
musican=get_formatted_name('jimi','hendrix')
print(musican)

musician = get_formatted_name('john','hooker','lee')
print(musician)
           
  • 傳回字典

函數可傳回任何類型的值,包括清單和字典等較複雜的資料結構。

person.py

def build_person(first_name, last_name):
    """傳回一個字典,其中包含有關一個人的資訊"""
    person = {'first': first_name, 'last': last_name}
    return person

musician = build_person('jimi', 'hendrix')
print(musician)
           
  • 結合使用函數和while循環
def get_formatted_name(first_name, last_name):
    """傳回整潔的姓名"""
    full_name = first_name + ' ' + last_name
    return full_name.title()


#這是一個無限循環!
''' while True:
    print("\nPlease tell me your name: ")
    f_name=input("First name: ")
    l_name=input("Last name: ")

    formatted_name=get_formatted_name(f_name,l_name)
    print("\nHello, "+formatted_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 + "!")
           

練習

#8-6 城市名:編寫一個名為 city_country()的函數,它接受城市的名稱及其所屬的國家。這個函數應傳回一個格式類似于下面這樣的字元串:"Santiago, Chile" ,至少使用三個 城市-國家對 調用這個函數,并列印它傳回的值。
def city_country(city_name,city_country):
    print(city_name.title()+" , "+city_country.title())

city_country('santiage','chile')
city_country('sydney','australia')
city_country('london','britain')
           
#8-7 專輯:編寫一個名為 make_album()的函數,它建立一個描述音樂專輯的字典。這個函數應接受歌手的名字和專輯名,并傳回一個包含這兩項資訊的字典。使用這個函數建立三個表示不同專輯的字典,并列印每個傳回的值,以核實字典正确地存儲了專輯的資訊。給函數 make_album()添加一個可選形參,以便能夠存儲專輯包含的歌曲數。如果調用這個函數時指定了歌曲數,就将這個值添加到表示專輯的字典中。調用這個函數,并至少在一次調用中指定專輯包含的歌曲數。
def make_album(singer_name,album_name,sings_number=''):
    albums={
        'singer name':singer_name.title(),
        'album name':album_name.title(),
    }
    if sings_number:
        albums['sings_number']=sings_number
    return albums
album=make_album('marry','love',6)
album1=make_album('jade','light')
print(album)
print(album1)
           
#8-8 使用者的專輯:在為完成練習 8-7 編寫的程式中,編寫一個 while 循環,讓使用者輸入一個專輯的歌手和名稱。擷取這些資訊後,使用它們來調用函數 make_album(),并将建立的字典列印出來。在這個 while 循環中,務必要提供退出途徑。
def make_album(singer_name, album_name):
    albums = {
        'singer_name': singer_name.title(),
        'album_name': album_name.title(),
    }
    message = print("\nThe album name is " + albums['album_name'] +
                    " and singer name is " + albums['singer_name'] + ".")
    return message

active = True
while active:
    message1 = "\n(Enter 'quit' to finish this input.)"
    message1 += "\nPlease enter name of one album: \t"
    album_name = input(message1)
    if album_name == 'quit':
        break
    message2 = "\nPlease enter singer name of this album: \t"
    singer_name = input(message2)
    if singer_name == 'quit':
        break
    make_album(singer_name, album_name)
           
  1. 傳遞清單

向函數傳遞清單很有用,這種清單包含的可能是名字、數字或更複雜的對象(如字典)。将清單傳遞給函數後,函數就能直接通路其内容。

greet_users.py

def greet_users(names):
    """向清單中的每位使用者都發出簡單的問候"""
    for name in names:
        msg="Hello, "+name.title()+"!"
        print(msg)
        
usernames=['hannah','try','margot']
greet_users(usernames)
           
  • 在函數中修改清單

将清單傳遞給函數後,函數就可對其進行修改。在函數中對這個清單所做的任何修改都是永久性的,這讓你能夠高效地處理大量的資料。

printing_models.py

#不使用函數
#首先建立一個清單,其中包含一些要列印的設計
unprinted_designs=['iphone case','robot pendant','dodecahedron']
completed_models=[]

#模拟列印每個設計,直到沒有未列印的設計為止
# 列印每個設計後,都将其移到清單completed_models中
while unprinted_designs:
    current_design=unprinted_designs.pop()

    #模拟根據設計制作的3D列印模型的過程
    print("Printing model: "+current_design)
    completed_models.append(current_design)

#顯示列印好的所有模型
print("\nThe following models have been printed: ")
for complete_model in completed_models:
    print(complete_model)
           

為了重新組織這些代碼,提高效率。第一個函數将負責處理列印設計的工作,而第二個将概述列印了哪些設計。

#使用函數
#第一個函數負責處理列印設計的工作,第二個概述列印了哪些設計
def print_models(unprinted_designs, completed_models):
    """ 
    模拟列印每個設計,直到沒有來列印的設計為止
    列印每個設計後,都将其移到清單completed_models中
    """
    while unprinted_designs:
        current_design = unprinted_designs.pop()

        #模拟根據設計制作3D列印模型的過程
        print("Printing model: " + current_design)
        completed_models.append(current_design)


def show_completed_models(completed_models):
    """ 顯示列印好的所有模型 """
    print("\nThe following models have been printed: ")
    for completed_model in completed_models:
        print(completed_model)


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

print_models(unprinted_designs, completed_models)
show_completed_models(completed_models)
           

程式示範了一種理念,即每個函數都應隻負責一項具體的工作。

  • 禁止函數修改清單

有時候,需要禁止函數修改清單,為了保留原來的檔案以供備案,為了解決這個問題,可向函數傳遞清單的副本而不是原件;這樣函數所做的任何修改都隻影響副本,而絲毫不影響原件。

function_name(list_name[:])
           

切片表示法[:]建立清單的副本。

print_models(unprinted_designs[:],completed_models)
           

雖然向函數傳遞清單的副本可保留原始清單的内容,但除非有充分的理由需要傳遞副本,否則還是應該講原始清單傳遞給函數,因為讓函數使用現成清單可避免花時間和記憶體建立副本,進而提高效率,在處理大型清單時尤其如此。

練習

# 8-9 魔術師:建立一個包含魔術師名字的清單,并将其傳遞給一個名為show_magicians()的函數,這個函數列印清單中每個魔術師的名字。
magicians=['jack','John','peter']
def show_magicians(magician_name):
    print("\nMagicians as follows: ")
    for magician in magicians:
        print("\t"+magician)

show_magicians(magicians)
           
# 8-10 了不起的魔術師:在你為完成練習 8-9 而編寫的程式中,編寫一個名為make_great()的函數,對魔術師清單進行修改,在每個魔術師的名字中都加入字樣“the Great”。調用函數 show_magicians(),确認魔術師清單确實變了。
magicians = ['jack', 'John', 'peter']

def make_great(name):
    for name in magicians:
        name = 'the Great ' + str(name)
    for i in range(3):
        magicians[i] = name
    return magicians


def show_magicians(magician_name):
    print("\nMagicians as follows: ")
    for magician in magician_name:
        print("\t" + magician)

make_great(magicians)
show_magicians(magicians)
           
# 8-11 不變的魔術師:修改你為完成練習 8-10 而編寫的程式,在調用函數make_great()時,向它傳遞魔術師清單的副本。由于不想修改原始清單,請傳回修改後的清單,并将其存儲到另一個清單中。分别使用這兩個清單來調用 show_magicians(),确認一個清單包含的是原來的魔術師名字,而另一個清單包含的是添加了字樣“the Great”的魔術師名字。
magicians = ['jack', 'John', 'peter']
current_magicians=[]

def make_great(magicians):
    for name in magicians:
        name='the Great '+str(name)
        current_magicians.append(name)
    return current_magicians

def show_magicians(magician_name):
    for magician in magician_name:
        print("\t" + magician)

make_great(magicians[:])
print("\nbefore magicians as follows: ")
show_magicians(magicians)
print("\nafter magicians as follows: ")
show_magicians(current_magicians)
           
  1. 傳遞任意數量的實參

有時候,預先不知道函數需要接受多少個實參,好在python允許函數從調用語句中收集任意數量的實參。

pizza.py

def make_pizza(*toppings):
    """ 列印顧客點的所有配料 """
    print(toppings)
    
make_pizza('pepperoni')
make_pizza('mushrooms','green peppers','extra cheese')
           

形參名*toppings中的*号讓python建立一個名為toppings的空元組,并将收到的所有值都封裝到這個元組中

#将print語句替換為一個循環,對配料清單進行周遊,并對顧客點的比薩進行描述
def make_pizza(*toppings):
    """ 概述要制作的pizza """
    print("\nMaking a pizza with the following toppings:")
    for topping in toppings:
        print("- "+topping)

make_pizza('pepperoni')
make_pizza('mushrooms','green peppers','extra cheese')
           
  • 結合使用位置實參和任意數量實參

如果要讓函數接受不同類型的實參,必須在函數定義中将接納任意數量實參的形參放在最後。

python線比對位置實參和關鍵字實參,再将餘下的實參都收集到最後一個形參中。

def make_pizza(size,*toppings):
    """ 概述要制作的披薩 """
    print("\nMaking a "+str(size)+"_inch pizza with the following toppings: ")
    for topping in toppings:
        print("- "+topping)
        
make_pizza(16,'pepperoni')
make_pizza(12,'mushrooms','green peppers','extra cheese')
           
  • 使用任意數量的關鍵字實參

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

可将函數編寫成能夠接受任意數量的鍵-值對–調用語句提供了多少就接受多少

user_profile.py

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)    
           

形參**user_info中的兩個*讓python建立一個名為user_info的空字典,并将收到的所有名稱-值對都封裝到這個字典中

編寫函數時,你可以以任何方式混合使用位置實參、關鍵字實參和任意數量的實參

練習

#8-12 三明治:編寫一個函數,它接受顧客要在三明治中添加的一系列食材。這個函數隻有一個形參(它收集函數調用中提供的所有食材),并列印一條消息,對顧客點的三明治進行概述。調用這個函數三次,每次都提供不同數量的實參。
def make_sandwichs(*toppings):
    print("\nMaking a sandwich with the following toppings:")
    for topping in toppings:
        print("\t"+topping)

make_sandwichs('pepperoni')
make_sandwichs('strawberry jam','romaine lettuce')
make_sandwichs('mushrooms','green peppers','extra cheese')
           
#8-13 使用者簡介:複制前面的程式 user_profile.py,在其中調用 build_profile()來建立有關你的簡介;調用這個函數時,指定你的名和姓,以及三個描述你的鍵-值對。
def build_profile(first, last, **user_info):
    """ 建立一個字典,其中包含我們知道的有關使用者的一切 """
    profile = {}
    profile['first_name'] = first.title()
    profile['last_name'] = last.title()
    for key, value in user_info.items():
        profile[key] = value.title()
    return profile


user_profile = build_profile('jade',
                             'marry',
                             location='london',
                             field='computer',sex='female')
print(user_profile)
           
#8-14 汽車:編寫一個函數,将一輛汽車的資訊存儲在一個字典中。這個函數總是接受制造商和型号,還接受任意數量的關鍵字實參。這樣調用這個函數:提供必不可少的資訊,以及兩個名稱—值對,如顔色和選裝配件。這個函數必須能夠像下面這樣進行調用:car = make_car('subaru', 'outback', color='blue', tow_package=True) 列印傳回的字典,确認正确地處理了所有的資訊。
def make_car(manufacter, types, **infos):
    specific_infos = {}
    specific_infos['manufacter'] = manufacter
    specific_infos['type'] = types
    for key, value in infos.items():
        specific_infos[key] = value
    return specific_infos


car = make_car('subaru', 'outback', color='blue', tow_package=True)
print(car)
           
  1. 将函數存儲在子產品中
    • 函數的優點之一是,使用它們可将代碼塊與主程式分離。
      • 通過給函數指定描述性名稱,可讓主程式容易了解的多。
      • 更進一步,将函數存儲在被稱為子產品的而獨立檔案中,再将子產品導入到主程式中。
      • import語句允許在目前運作的程式檔案夾中使用子產品的代碼。
    • 通過将函數存儲在獨立的檔案中,可隐藏程式代碼的細節,将重點放在程式的高層邏輯上。
      • 這能在衆多不同的程式中重用函數
      • 将函數存儲在獨立檔案中後,可與其他程式員共享這些檔案而不是整個程式、
      • 知道如何導入函數還能讓你使用其他程式員編寫的函數庫
  • 導入整個子產品

要讓函數是可導入的,得先建立子產品。

子產品 是擴充名為.py的檔案,包含要導入到程式中的代碼。

pizza.py

def make_pizza(size,*toppings):
    """ 概述要制作的披薩 """
    print("\nMaking a "+str(size)+"_inch pizza with the following toppings: ")
    for topping in toppings:
        print("- "+topping)
           

making_pizzas.py

import pizza

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

python讀取這個檔案時,代碼行import pizza讓python打開檔案pizza.py,并将其中的所有函數都複制到這個程式中,但是這個複制是看不到的,隐藏在“幕後”的,這裡在making_pizzas.py中可以使用pizza.py中定義的所有函數。

格式:導入子產品名稱.函數名( ),即module_name.function_name()

  • 導入特定的函數

格式:from module_name import function_name

導入多個函數:from module_name import function_0, function_1, function_2

from pizza import make_pizza

make_pizza(16, 'pepperoni')
make_pizza(12, 'mushrooms','green peppers','extra cheese')
           

這種文法,調用函數時無需使用句點“.”

  • 使用as給函數指定别名

如果要導入的函數的名稱可能與程式中現有的名稱沖突,或者函數的名稱太長,可指定簡短而獨一無二的别名–函數的另一個名稱,類似于外号。

使用關鍵字as将函數重命名為提供的别名,避免與程式中的函數混淆重複

from pizza import make_pizza as mp

mp(16, 'pepperoni')
mp(12, 'mushrooms', 'green peppers', 'extra cheese')
           

格式:from module_name import function_name as fn

  • 使用as給子產品指定别名

可以給子產品指定别名。通過給子產品指定簡短的别名,使得調用子產品中的函數更加輕松

import pizza as p

p.make_pizza(16, 'pepperoni')
p.make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')
           

上述import語句給子產品pizza指定了别名p,但該子產品中所有函數的名稱都沒變。

這樣不僅能使代碼更簡潔,還可以讓你不再關注子產品名,而專注于描述性的函數名。這些函數名明确地指出了函數的功能,對了解代碼而言,它們比子產品名更重要。

格式:import module_name as mn

  • 導入子產品中的所有函數

使用星号(*)運算符可以讓python導入子產品中的所有函數

from pizza import *

make_pizza(16, 'pepperoni')
make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')
           

格式:from module_name import *

import語句中的*讓Python将子產品pizza中的每個函數都複制到這個程式檔案中。由于導入了每個函數,可通過名稱來調用每個函數,而無需使用句點表示法。

然而,使用并非自己編寫的大型子產品時,最好不要采用這種導入方法:如果子產品中有函數的名稱與你的項目中使用的名稱相同,可能導緻意想不到的結果:Python可能遇到多個名稱相同的函數或變量,進而覆寫函數,而不是分别導入所有的函數。

最佳的做法是,要麼隻導入你需要使用的函數,要麼導入整個子產品并使用句點表示法。這能讓代碼更清晰,更容易閱讀和了解。

  1. 函數編寫指南
  • 應給函數指定描述性名稱,且隻在其中使用小寫字母和下劃線
    • 描述性名稱可幫助你和别人明白代碼想要做什麼
    • 給子產品命名時也應遵循上述約定。
  • 每個函數都應包含簡要地闡述其功能的注釋,該注釋應緊跟在函數定義後面,并采用文檔字元串格式
    • 文檔良好的函數讓其他程式員隻需閱讀文檔字元串中的描述就能夠使用它
    • 他們完全可以相信代碼如描述的那樣運作;
    • 隻要知道函數的名稱、需要的實參以及傳回值的類型,就能在自己的程式中使用它
  • 給形參指定預設值時,等号兩邊不要有空格
    • 對于函數調用中的關鍵字實參,也應遵循這種約定
  • PEP 8 建議代碼行的長度不要超過79字元,這樣隻要編輯器視窗适中,就能看到整行代碼
    • 如果形參很多,導緻函數定義的長度超過了79字元,
    • 可在函數定義中輸入左括号後按Enter鍵,
    • 并在下一行按兩次Tab鍵,進而将形參清單和隻縮進一層的函數體區分開來
    • 大多數編輯器都會自動對齊後續參數清單行,使其縮程序度與你給第一個參數清單行指定的縮程序度相同
  • 如果程式或子產品包含多個函數,可使用兩個空行将相鄰的函數分開,這樣将更容易知道前一個函數在什麼地方結束,下一個函數從什麼地方開始
  • 所有的import語句都應放在檔案開頭,唯一例外的情形是,在檔案開頭使用了注釋來描述整個程式

練習

#8-15 列印模型:将示例 print_models.py 中的函數放在另一個名為 printing_ functions.py 的檔案中;在 print_models.py 的開頭編寫一條 import 語句,并修改這個檔案以使用導入的函數。
''' print_models.py '''
#第一個函數負責處理列印設計的工作,第二個概述列印了哪些設計
def print_models(unprinted_designs, completed_models):
    """ 
    模拟列印每個設計,直到沒有來列印的設計為止
    列印每個設計後,都将其移到清單completed_models中
    """
    while unprinted_designs:
        current_design = unprinted_designs.pop()

        #模拟根據設計制作3D列印模型的過程
        print("Printing model: " + current_design)
        completed_models.append(current_design)


def show_completed_models(completed_models):
    """ 顯示列印好的所有模型 """
    print("\nThe following models have been printed: ")
    for completed_model in completed_models:
        print(completed_model)

''' print_functions.py '''
import printing_models as pm

unprinted_designs = ['iphone case', 'robot pendant', 'dodecahedron']
completed_models = []
pm.print_models(unprinted_designs, completed_models)
pm.show_completed_models(completed_models)
           
#8-16 導入:選擇一個你編寫的且隻包含一個函數的程式,并将這個函數放在另一個檔案中。在主程式檔案中,使用下述各種方法導入這個函數,再調用它:
# import module_name
# from module_name import function_name
# from module_name import function_name as fn
# import module_name as mn
# from module_name import *

''' user_profile.py '''
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


''' read_profile.py '''
#方法一
import user_profile
read_profile = user_profile.build_profile('albert',
                                          'einstein',
                                          location='princeton',
                                          field='physics')
print(read_profile)

#方法二
from user_profile import build_profile
read_profile = build_profile('albert',
                             'einstein',
                             location='princeton',
                             field='physics')
print(read_profile)

#方法三
from user_profile import build_profile as bp
read_profile = bp('albert', 'einstein', location='princeton', field='physics')
print(read_profile)

#方法四
import user_profile as up
read_profile = up.build_profile('albert',
                                'einstein',
                                location='princeton',
                                field='physics')
print(read_profile)

#方法五
from user_profile import *
read_profile = build_profile('albert',
                             'einstein',
                             location='princeton',
                             field='physics')
print(read_profile)