Python编程:从入门到实践——第8章、函数(附课后题)

定义函数

def greet_user():
    """显示简单的问候语(docstring 文档字符串)"""
    print("Hello!")
greet_user()

向函数传递信息

def greet_user1(username):
    print("Hello," + username.title() + "!")
greet_user1("jack")

实参和形参

定义函数时,括号内的定义的变量即一个形参
实参是调用该函数时传递给函数的信息。
过程为:实参传递给形参

位置实参,基于实参顺序

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')

关键字实参,传递给函数的 名称——值对,在实参中将名称与值关联起来,无需考虑实参顺序

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')
describe_pet(pet_name='harry',animal_type= 'hamster')
#注意 使用关键字实参时,务必准确地指定函数定义中的形参名

默认值

编写函数时,可以给形参指定默认值,调用提供实参时,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='willie')
describe_pet('willie')
describe_pet(pet_name='harry', animal_type='hamster')
#使用默认值时,在形参列表中必须先列出没有默认值的形参,再列出有默认值的实参,能让Python更好的解读位置实参

返回值

使用return语句,将函数处理后的值,返回到调用该函数的代码行,简化主程序
返回简单值

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_names(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()
musician = get_formatted_names('jimi','hendrix')
print(musician)
musician = get_formatted_names('john','hooker','lee')
print(musician)

返回字典

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_person2(first_name,last_name,age=''):
    person = {'first':first_name,'last':last_name}
    if age:
        person['age'] = age
    return person
musician2 = build_person2('jack','chen',age = 27)
print (musician2)

结合使用函数和while 循环

def get_formentted_name(first_name,last_name):
    """返回整洁的姓名"""
    full_name = first_name + ' ' + last_name
    return full_name.title()
#这是一个无限循环
while True:
    print("\nPlease tell me your name:")
    print("(enter 'quit'at any time to quit)")
    f_name = input("First name:")
    if f_name == 'quit':
        break
    l_name = input("Last name:")
    if l_name == 'quit':
        break
    formentted_name = get_formentted_name(f_name,l_name)
    print("\nHello," + formentted_name + "!")

传递列表

def greet_users(names):
    """向列表中的每位用户都发出简单的问候"""
    for name in names:
        msg = "Hello, " + name.title() + "!"
        print(msg)
usernames = ['李明','lucy','张三','李四']
greet_users(usernames)

在函数中修改列表

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)
#不修改原有列表,进行副本创建print_models(unprinted_designs[:],completed_models)
show_completed_models(completed_models)

传递任意数量的实参

def make_pizza(*toppings):
    #形参前的*号,让Py建立一个名为toppings的空元组,并将实参封装在元组内
    """打印顾客点的所有配料"""
    print(toppings)
make_pizza('peperoni')
make_pizza('mushrooms','green peppers','extra cheese')
#循环打印处理
def make_pizza(*toppings):
    #形参前的*号,让Py建立一个名为toppings的空元组,并将实参封装在元组内
    """打印顾客点的所有配料"""
    print("\nMaking a pizza with the following toppings:")
    for topping in toppings:
        print('-' + topping)
make_pizza('peperoni')
make_pizza('mushrooms','green peppers','extra cheese')

结合使用位置实参和任意数量实参

def make_pizza(size,*toppings):
    """概述制作的比萨"""
    print("\nMake a " + str(size) + "-inch pizza with the following toppings:")
    for topping in toppings:
        print("-" + topping)
make_pizza(16,'pepperoni')
make_pizza(12,'mushrooms','green pepers','extra cheese')

使用任意数量的关键字实参

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)

8.6 将函数存储在模块中

#实现代码块与主程序分离,将函数存储在被称为模块的py独立文件中,再讲模块导入主程序中
#import 语句允许在当前运行的程序文件中使用模块中的代码

8.6.1 导入整个模块

#需先建立有函数的独立模块的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)
#在pizza.py所在的目录中创建另外一个名字为making_pizza.py的文件,在此文件中导入刚创建的pizza模块,通过 模块.函数名()的模式来使用模块内的任意函数
import pizza
pizza.make_pizza(16,'pepperoni')
pizza.make_pizza(12,'mushrooms','green peppers','extra cheese')

8.6.2 导入特定的函数

#语法:from module_name import function_name
from pizza import make_pizza 
#由于现式的引入函数,所以该函数不需要模块.函数使用,直接使用函数名即可
make_pizza(16,'pepperoni')
make_pizza(12,'mushrooms','green peppers','extra cheese')

8.6.3 使用as 给函数指定别名

#要导入函数名过长或有冲突,可as指定别名,语法:from module_name import function_name as fn
from pizza import make_pizza as mp
mp(16,'pepperoni')
mp(12,'mushrooms','green peppers','extra cheese')

8.6.4 使用as 给模块指定别名

#对使用模块起别名,语法:import module_name as m
import pizza as p 
p.make_pizza(16,'pepperoni')
p.make_pizza(12,'mushrooms','green peppers','extra cheese')

.6.5 导入模块中的所有函数

#使用星号(* )运算符可让Python导入模块中的所有函数
from pizza import *
make_pizza(16,'pepperoni')
make_pizza(12,'mushrooms','green peppers','extra cheese')

导入模块注意:

import 语句中的星号让Python将模块pizza 中的每个函数都复制到这个程序文件中。由于导入了每个函数,可通过名称来调用每个函数,而无需使用句点表示法。然而,使用
并非自己编写的大型模块时,最好不要采用这种导入方法:如果模块中有函数的名称与你的项目中使用的名称相同,可能导致意想不到的结果:Python可能遇到多个名称相同的函
数或变量,进而覆盖函数,而不是分别导入所有的函数。
最佳的做法是,要么只导入你需要使用的函数,要么导入整个模块并使用句点表示法。这能让代码更清晰,更容易阅读和理解。这里之所以介绍这种导入方法,只是想让你在阅
读别人编写的代码时,如果遇到类似于下面的import 语句,能够理解它们:
from module_name import *

8.7 函数编写指南

编写函数时,需要牢记几个细节。应给函数指定描述性名称,且只在其中使用小写字母和下划线。描述性名称可帮助你和别人明白代码想要做什么。给模块命名时也应遵循上述
约定。
每个函数都应包含简要地阐述其功能的注释,该注释应紧跟在函数定义后面,并采用文档字符串格式。文档良好的函数让其他程序员只需阅读文档字符串中的描述就能够使用
它:他们完全可以相信代码如描述的那样运行;只要知道函数的名称、需要的实参以及返回值的类型,就能在自己的程序中使用它。
给形参指定默认值时,等号两边不要有空格:
def function_name(parameter_0, parameter_1='default value')
对于函数调用中的关键字实参,也应遵循这种约定:
function_name(value_0, parameter_1='value')
建议代码行的长度不要超过79字符,这样只要编辑器窗口适中,就能看到整行代码。如果形参很多,导致函数定义的长度超过了
79字符,可在函数定义中输入左括号后按回车键,并在下一行按两次Tab键,从而将形参列表和只缩进一层的函数体区分开来。
大多数编辑器都会自动对齐后续参数列表行,使其缩进程度与你给第一个参数列表行指定的缩进程度相同:
def function_name(
            parameter_0, parameter_1, parameter_2,
            parameter_3, parameter_4, parameter_5):
    function baby...

如果程序或模块包含多个函数,可使用两个空行将相邻的函数分开,这样将更容易知道前一个函数在什么地方结束,下一个函数从什么地方开始。
所有的import 语句都应放在文件开头,唯一例外的情形是,在文件开头使用了注释来描述整个程序。

练习题

#8-1 
#消息 :编写一个名为display_message() 的函数,它打印一个句子,指出你在本章学的#是什么。调用这个函数,确认显示的消息正确无误。
def dispaly_message():
    print("我在本章学习Python函数基础知识!")
dispaly_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("西游记")
#8-6 
#城市名 :编写一个名为city_country() 的函数,它接受城市的名称及其所属的国家。
#这个函数应返回一个格式类似于下面这样的字符串:
def city_country(city,country):
    city_country = city + ',' + country
    return(city_country)
ex = city_country('上海','中国')
print(ex)
#8-7 
#专辑 :编写一个名为make_album() 的函数,它创建一个描述音乐专辑的字典。这个函数#应接受歌手的名字和专辑名,并返回一个包含这两项信息的字典。使
#用这个函数创建三个表示不同专辑的字典,并打印每个返回的值,以核实字典正确地存储了专辑的信息。
#给函数make_album() 添加一个可选形参,以便能够存储专辑包含的歌曲数。如果调用这个函数时指定了歌曲数,就将这个值添加到表示专辑的字典中。调用这个
#函数,并至少在一次调用中指定专辑包含的歌曲数。
def make_album(songer,album,songnum = ''):
    if songnum:
        music_album = {'songer':songer,'album':album,'songnum':songnum}
    else:
        music_album = {'songer':songer,'album':album}
    return music_album
muscicalbum = make_album('周杰伦','七里香')
muscicalbum2 = make_album('周杰伦','七里香','20')
print(muscicalbum)
print(muscicalbum2)
#8-8
#用户的专辑 :在为完成练习8-7编写的程序中,编写一个while 循环,让用户输入一个专辑的歌手和名称。获取这些信息后,使用它们来调用函
#数make_album() ,并将创建的字典打印出来。在这个while 循环中,务必要提供退出途径。
def make_album():
    while True:
        print("输入英文'quit',即退出程序!")
        song_name = input("输入歌手名:")
        if song_name == 'quit':
            break
        song_album = input("输入专辑名:")
        if song_album == 'quit':
            break
        song_num = input("输入专辑歌曲数:")
        if song_num == 'quit':
            break
        music_album = {'歌手名':song_name,'专辑名':song_album,'专辑曲数':song_num}
        print(music_album)
musicAlbum = make_album()
#8-9
#魔术师 :创建一个包含魔术师名字的列表,并将其传递给一个名为show_magicians() 的函数,这个函数打印列表中每个魔术师的名字
def show_magicians(magicians):
    for magician in magicians:
        print(magician.title())
magicians_name = ['刘千','daven','Smaitch','王五','二毛']
show_magicians(magicians_name)
#8-10
#了不起的魔术师 :在你为完成练习8-9而编写的程序中,编写一个名为make_great() 的函数,对魔术师列表进行修改,在每个魔术师的名字中都加入字样“the Great”。调用函数show_magicians() ,确认魔术师列表确实变了。
def make_great(magicians,update_magician):
    while magicians:
        update = 'The Great ' + magicians.pop()
        update_magician.append(update)

def show_magicians(magicians):
    for magician in magicians:
        print(magician.title())
magicians_name = ['刘千','daven','Smaitch','王五','二毛']
update_magician = []
make_great(magicians_name,update_magician)
show_magicians(update_magician)
#8-11
#不变的魔术师 :修改你为完成练习8-10而编写的程序,在调用函数make_great() 时,向它传递魔术师列表的副本。由于不想修改原始列表,请返回修改后的
#列表,并将其存储到另一个列表中。分别使用这两个列表来调用show_magicians() ,确认一个列表包含的是原来的魔术师名字,而另一个列表包含的是添加了字
#样“the Great”的魔术师名字。
def make_great(magicians,update_magician):
    while magicians:
        update = 'The Great ' + magicians.pop()
        update_magician.append(update)

def show_magicians(magicians):
    for magician in magicians:
        print(magician.title())
magicians_name = ['刘千','daven','Smaitch','王五','二毛']
update_magician = []
make_great(magicians_name[:],update_magician)
show_magicians(update_magician)
show_magicians(magicians_name)
#8-12 
#三明治 :编写一个函数,它接受顾客要在三明治中添加的一系列食材。这个函数只有一个形参(它收集函数调用中提供的所有食材),并打印一条消息,对顾客
#点的三明治进行概述。调用这个函数三次,每次都提供不同数量的实参。
def make_sandwich(*foods):
    """接受顾客对三明治添加的食材"""
    print("您要求对三明治添加的食材:")
    print(foods)
make_sandwich('鸡肉','海带')
make_sandwich('牛肉','萝卜','土豆')
#8-13 
#用户简介 :复制前面的程序user_profile.py,在其中调用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('刘','升',location = '西安',job = 'Tester',sex = '男')
print(user_profile)
#8-14 汽车 :编写一个函数,将一辆汽车的信息存储在一个字典中。这个函数总是接受制造商和型号,还接受任意数量的关键字实参。这样调用这个函数:提供必不可
#少的信息,以及两个名称—值对,如颜色和选装配件。这个函数必须能够像下面这样进行调用:
def make_car(manufacturer,model,**car_info):
    carfile = {}
    carfile['manufacturer'] = manufacturer
    carfile['model'] = model
    for key,value in car_info.items():
        carfile[key] = value
    return  carfile
car = make_car('subaru', 'outback', color='blue', tow_package=True)
print(car)
#8-15 
#打印模型 :将示例print_models.py中的函数放在另一个名printing_functions.py的文件中;在print_models.py的开头编写一条import 语句,并修改这个文件以使用导
#入的函数。

#printing_functions.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_models.py
from printing_functions import *
unprinted_designs = ['iphone case','robot pendant','dodecahedron']
completed_models = []
print_models(unprinted_designs,completed_models)
#不修改原有列表,进行副本创建print_models(unprinted_designs[:],completed_models)
show_completed_models(completed_models)
#8-16
#导入 :选择一个你编写的且只包含一个函数的程序,并将这个函数放在另一个文件中。在主程序文件中,使用下述各种方法导入这个函数,再调用它:
#module_print.py
def function_text(text):
    """输入文字"""
    print(text)

#test_print.py    
#第一种导入
import module_print
module_print.function_text('你好')
#第二种导入
from module_print import function_text
function_text('你好')
#第三种导入
from module_print import function_text as fn
fn('你好')
#第四种导入
import module_print as mn
mn.function_text('你好')
#第五种导入
from module_print import *
function_text('你好')

猜你喜欢

转载自blog.csdn.net/github_35707894/article/details/80657329