《Python编程从入门到实践》学习笔记<8>:函数

  Python中的函数就是带名字的代码块,主要用于完成具体的工作。Python的函数用def关键字来声明,定义好函数名后,后面的所金行都属于函数的函数体,如下所示:

def test(t1):  #def声明构建函数,函数名为test,其中t1是用来传递参数的形参
    print(t1)  #此处是函数的函数体

test('t2')     #调用函数test(),函数内部的t2是被传递的值,即实参


#执行结果如下:
t2

  在Python的函数中,形参是函数完成其工作所需的一项信息,实参是调用函数式传递给函数的信息。通俗来说,形参用来接收调用方法时传递过去的实参,在接受到实参中的值以后,将其带入函数体中进行处理;而实参则是调用函数时被传递的值。向函数传递 实参的方法有很多,常见的方法有三个,即位置实参、关键字实参和默认值三种,如下所示:

##位置实参,实参的顺序要和形参的顺序一致
def describe_pet(animmal_type,pet_name):
    """显示宠物的信息"""
    print("
I have a " + animmal_type + ".")
    print("My " + animmal_type + "'s name is " + pet_name.title() + ".")

describe_pet('hamste','harry')

#执行结果如下所示:
I have a hamste.
My hamste's name is Harry.


#关键字实参,在调用时指定形参对应的实参,即键值对,
#由于调用实参时指定了值,因此实参顺序可以不考虑
def describe_pet(animmal_type,pet_name):
    """显示宠物的信息"""
    print("
I have a " + animmal_type + ".")
    print("My " + animmal_type + "'s name is " + pet_name.title() + ".")

describe_pet(animmal_type = 'hamste',pet_name = 'harry')

#执行结果如下所示:
I have a hamste.
My hamste's name is Harry.



#默认值,在定义形参的时候,将部分或全部形参附上默认值,
#当调用实参时,可以不引用赋有默认值的形参,这样输出结果就是默认值,
#如果跟默认值不符,也可以在调用实参的时候给实参赋值
def describe_pet(animmal_type,pet_name  = 'ben'):
    """显示宠物的信息"""
    print("
I have a " + animmal_type + ".")
    print("My " + animmal_type + "'s name is " + pet_name.title() + ".")

describe_pet(animmal_type = 'hamste',pet_name = 'harry')

#执行结果如下所示:
I have a hamste.
My hamste's name is Harry.

  调用函数的方式多种多样,在适合的环境下使用正确的方法,需要大量的练习和开发过程中的经验积累,当然容易理解很重要,课后习题答案如下所示:

--8-4
def make_shirt(size,printing = '英文'):
    print("这件衣服的尺码是" + size + ",上面印着" + printing + ".")

make_shirt('xl','汉字')

#输出结果如下所示:
这件衣服的尺码是xl,上面印着汉字.

  对于函数的复杂应用,不得不提到返回值!函数处理返回的值被称为返回值,用return来声明,返回值的使用能够将程序大部分繁中的工作转移到函数中去,从而简化程序,如下所示:

#让实参变得可选
def get_formatted_name(first_name,last_name,middle_name = ''):
    """返回整洁的姓名"""
    full_name = first_name + ' ' + middle_name + ' ' + last_name
    return full_name.title()

musician = get_formatted_name('john','lee','hooker')
print(musician)

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

#输出结果如下所示:
John Hooker Lee
Jimi  Hendrix

  上例中定义函数get_formatted_name(),包含三个形参first_name、last_name和middle_name,其中形参middle_name因为赋默认值,因此放最后,然后执行函数体,将执行结果赋值给变量full_name,并在执行完毕后将执行结果full_name作为返回值,返回给调用get_formatted_name()函数的变量musician,然后打印变量musician,实现整个函数。

  除了上例中返回的结果外,返回值还能返回字典,如下例所示:

#形参age,赋默认值为空
#当实参未调用age时,默认赋值为空
#当实参调用age时,进入if判断,age为字典person的键
#因此person['age'] 的值为形参age,调用的时候,数值传入形参age中
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',age = '16')
print(musician)

#输出结果如下所示:
{'first': 'jimi', 'last': 'hendrix', 'age': '16'}

  上例中定义函数build_person,包含三个形参first_name,last_name和age,其中形参age赋默认值为空,定义字典person用于存储实参数值,由于age有默认值空,因此进入if判断,当age有值时加入字典person,处理完毕后返回结果person,并将返回的结果存入调用方法build_person的变量musician,打印变量musician可获得结果。

  函数体的逻辑可以简单也可以复杂,比如加上while循环的使用,可以让功能更加强大,如下所示:

#函数统一了输出的格式,while循环实现了函数的实参值处理
def get_formatted_name(first_name,last_name):
    """返回整洁的姓名"""
    full_name = first_name + ' ' + last_name
    return full_name.title()

while True:
    print("
Please tell me you 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("
Hello," + formatted_name + "!")

#输出结果如下所示:
Please tell me you name:
(enter 'q' at any time to quit)
First_name:a
Last_name:b

Hello,A B!

Please tell me you name:
(enter 'q' at any time to quit)
First_name:q

进程完成,退出码 0

  上例中处理方函数内while循环问题,并不复杂,下面是课后习题答案,如下所示:

#8-6
def city_country(city,country):
    cc = city + "," + country
    return cc.title()

regime = city_country('santuago','chile')
print((regime))

#输出结果如下所示:
Santuago,Chile


#8-7
def make_album(singer,album,number = ''):
    works = {'singer':singer,'album':album}
    if number:
        works['number'] = number
    return works

result = make_album('周杰伦','Jay',10)
print(result)

#输出结果如下所示:
{'singer': '周杰伦', 'album': 'Jay', 'number': 10}



#8-8
def make_album(singer,album):
    works = singer + ',' + album
    return works.title()

while True:
    print("请输入你喜欢的歌手信息")
    singer_name = input("singer:")
    if singer_name == 'q':
        break
    album_name = input("album:")
    if album_name == 'q':
        break

    result = make_album(singer_name,album_name)
    print(result)
    
#输出结果如下所示:
请输入你喜欢的歌手信息
singer:周杰伦
album:Jay
周杰伦,Jay
请输入你喜欢的歌手信息
singer:q

进程完成,退出码 0



    
#8-8变形,增加number形参处理专辑内歌曲数量问题
def make_album(singer,album,number = ''):
    works = {'singer':singer,'album':album}
    if number:
        works['number'] = number
        output_works = works['singer'] + "," + works['album'] + "," + works['number']
    else:
        output_works = works['singer'] + "," + works['album']
    return output_works

while True:
    print("请输入你喜欢的歌手信息")
    singer_name = input("singer:")
    if singer_name == 'q':
        break
    album_name = input("album:")
    if album_name == 'q':
        break
    numbers = input("number:")
    if numbers == 'q':
        break
    result = make_album(singer_name,album_name,numbers)
    print(result)
        
#输出结果如下所示:
请输入你喜欢的歌手信息
singer:周杰伦
album:Jay
number:10
周杰伦,Jay,10
请输入你喜欢的歌手信息
singer:周杰伦
album:Jay
number:
周杰伦,Jay
请输入你喜欢的歌手信息

  复杂的内容有时会通过列表传递到函数中进行处理,如下所示:

#以列表的形式向函数传参,通常结构如下
def greet_users(names):
    """向列表中的每位用户发出简单的问候"""
    for name in names:
        msg = "Hwllo," + name.title() + "!"
        print(msg)

username = ['hannah','ty','margot']
greet_users(username)

#输出结果如下所示:
Hwllo,Hannah!
Hwllo,Ty!
Hwllo,Margot!



#复杂的传参如下所示、
#定义函数print_models,包含形参unprinted_designs和completed_models
def print_models(unprinted_designs,completed_models):
    """模型打印每个设计,直到没有未打印的设计为止
        打印每个设计后,都将其移到列表completed_mode
        ls中
    """
    #执行while循环,将列表unprinted_designs中的数据传递到current_desgion中
    while unprinted_designs:
        current_desgion = unprinted_designs.pop()

        #模拟根据设计制作3D打印模型的过程,即打印列表传递的过程
        print("Prining model: " + current_desgion)
        completed_models.append(current_desgion)

def show_completed_models(completed_model):
    """显示打印好的模型"""
    print("
The following modles have been printed:")
    for completed_model in completed_model:
        print(completed_model)

#创建列表unprinted_designs和completed_models
unprinted_designs = ['iphone case','robot pendant','dodecahedron']
completed_models = []

#定义变量print_models和show_completed_models负责传参
print_models(unprinted_designs,completed_models)
show_completed_models(completed_models)

#输出结果如下所示:
Prining model: dodecahedron
Prining model: robot pendant
Prining model: iphone case

The following modles have been printed:
dodecahedron
robot pendant
iphone case

   课后习题答案如下所示:

#8-9
def show_magicians(names):
    for name in names:
        print(name)

names = ['a','b','c']
show_magicians(names)

#输出结果如下所示:
a
b
c




#8-10
def make_great(unnames,names):
    while unnames:
        sname = unnames.pop()
        names.append(sname)

def show_magicians(names):
    for name in names:
        print(name.title() + " the Great")

unnames = ['a','b','c']
names = []

make_great(unnames,names)
show_magicians(names)

#输出结果如下所示:
C the Great
B the Great
A the Great




#8-11
def make_great(unnames,names):
    while unnames:
        sname = unnames.pop()
        names.append(sname.title() + " the Great")

def show_magicians(names):
    for name in names:
        print(name)

unnames = ['a','b','c']
names = []

make_great(unnames[:],names)   #unnames[:]的作用在于传参时传递的是列表unnames的复制列表,不会修改原数据
show_magicians(names)

print(unnames)
print(names)

#输出结果如下所示:
#8-9
def show_magicians(names):
    for name in names:
        print(name)

names = ['a','b','c']
show_magicians(names)

#输出结果如下所示:
a
b
c




#8-10
def make_great(unnames,names):
    while unnames:
        sname = unnames.pop()
        names.append(sname)

def show_magicians(names):
    for name in names:
        print(name.title() + " the Great")

unnames = ['a','b','c']
names = []

make_great(unnames,names)
show_magicians(names)

#输出结果如下所示:
C the Great
B the Great
A the Great




#8-11
def make_great(unnames,names):
    while unnames:
        sname = unnames.pop()
        names.append(sname.title() + " the Great")

def show_magicians(names):
    for name in names:
        print(name)

unnames = ['a','b','c']
names = []

make_great(unnames[:],names)   #unnames[:]的作用在于传参时传递的是列表unnames的复制列表,不会修改原数据
show_magicians(names)

print(unnames)
print(names)

#输出结果如下所示:
C the Great
B the Great
A the Great
['a', 'b', 'c']
['C the Great', 'B the Great', 'A the Great']

  处理日常问题时,有时因为数据量庞大,可能不知道你有多少个参数传递进来,因此Python有关于传递任意实参的处理方式,如下所示:

def make_pizz(*toppings):  #在形参前面添加*,表示创建名为toppings的元组,将所有值都封装进去
    """打印顾客点的所有配料"""
    print("
Making a pizz with the following topping:")
    for topping in toppings:
        print("- " + topping)

make_pizz('pepperoni')
make_pizz('mushrooms', 'green peppers', 'extra cheese')

#输出结果如下所示:
Making a pizz with the following topping:
- pepperoni

Making a pizz with the following topping:
- mushrooms
- green peppers
- extra cheese





#存在知道部分实参数量的情况,此时可用以下方式处理,知道实参的数据正常处理,不知道的用*批量处理
def make_pizz(size,*toppings):
    """概述要制作的披萨"""
    print("
Making a " + str(size)+
          "-inch pizz with the following toppings:")
    for topping in toppings:
        print("- " + topping)

make_pizz(16,'pepperoni')
make_pizz(34,'mushrooms', 'green peppers', 'extra cheese')
make_pizz(22)

#输出结果如下所示:
Making a 16-inch pizz with the following toppings:
- pepperoni

Making a 34-inch pizz with the following toppings:
- mushrooms
- green peppers
- extra cheese

Making a 22-inch pizz with the following toppings:




#有时需要接收任意实参,但不知道实参是什么样的信息,此时可将函数编写成能够接受任意数量的键值对,将数据存放在字典中
def build_profile(first,last,**user_info):    ##形参前面加两个**,表示创建名为user_info的字典
    """创建一个字典,其中包含我们知道的有关用户的一切"""
    profile = {}
    profile["first_name"] = first
    profile['last_name'] = last
    
    #该出循环为=是为了任意实参取数,将实参传入入的键值对取出键和值,以profile[key] = value的形式存入字典profile中
    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)

#输出结果如下所示:
{'first_name': 'albert', 'last_name': 'einstein', 'location': 'princeton', 'field': 'physics'}

  习题答案如下:

#8-12
def sandwich_toppings(*toppings):
    print(toppings)

sandwich_toppings('mushroom','tomato','green peppers')

#输出结果如下所示:
('mushroom', 'tomato', 'green peppers')





#8-14
def make_car(manufacturer,model,**other_information ):
    car_information = {}
    car_information['manufacturer_name'] = manufacturer
    car_information["model_value"] = model

    for key,value in other_information.items():
        car_information[key] = value
    return car_information

car = make_car('subaru','outback',color = 'blue',tow_package = True)
print(car)

#输出结果如下所示:
'manufacturer_name': 'subaru', 'model_value': 'outback', 'color': 'blue', 'tow_package': True}

  函数的优点之一是可以将代码块和主程序分离,将函数存储在称为模块的独立文件中,通过import导入的方式进入主程序,如下所示:

#test.py
def make_pizz(size,*toppings):
    """概述要制作的披萨"""
    print("
Making a " + str(size) +
          "-invh pizz with the following toppings:")
    for topping in toppings:
        print("- " + topping)
###############################
#导入整个模块
#test2.py
import test1

test1.make_pizz(16,'pepperoni')
test1.make_pizz(12,'mushroom','green peppers','extra cheese')
print("-----------------导入整个模块-----------------")
###############################
#导入模块中的特定函数,多个函数可用逗号隔开
from test1 import make_pizz

make_pizz(16,'pepperoni')
make_pizz(12,'mushroom','green peppers','extra cheese')
print("-----------------导入模块中的特定函数-----------------")
###############################
#给导入模块中的特定函数起别名
from test1 import make_pizz as mp

mp(16,'pepperoni')
mp(12,'mushroom','green peppers','extra cheese')
print("-----------------给导入模块中的特定函数起别名-----------------")
###############################
#给导入模块起别名
import test1 as p

p.make_pizz(16,'pepperoni')
p.make_pizz(12,'mushroom','green peppers','extra cheese')
print("-----------------给导入模块起别名-----------------")
###############################
#导入模块中的所有函数
from test1 import *

make_pizz(16,'pepperoni')
make_pizz(12,'mushroom','green peppers','extra cheese')
print("-----------------导入模块中的所有函数-----------------")

#输出结果如下所示:
Making a 16-invh pizz with the following toppings:
- pepperoni

Making a 12-invh pizz with the following toppings:
- mushroom
- green peppers
- extra cheese
-----------------导入整个模块-----------------

Making a 16-invh pizz with the following toppings:
- pepperoni

Making a 12-invh pizz with the following toppings:
- mushroom
- green peppers
- extra cheese
-----------------导入模块中的特定函数-----------------

Making a 16-invh pizz with the following toppings:
- pepperoni

Making a 12-invh pizz with the following toppings:
- mushroom
- green peppers
- extra cheese
-----------------给导入模块中的特定函数起别名-----------------

Making a 16-invh pizz with the following toppings:
- pepperoni

Making a 12-invh pizz with the following toppings:
- mushroom
- green peppers
- extra cheese
-----------------给导入模块起别名-----------------

Making a 16-invh pizz with the following toppings:
- pepperoni

Making a 12-invh pizz with the following toppings:
- mushroom
- green peppers
- extra cheese
-----------------导入模块中的所有函数-----------------

Making a 16-invh pizz with the following toppings:
- pepperoni

Making a 12-invh pizz with the following toppings:
- mushroom
- green peppers
- extra cheese
-----------------导入整个模块-----------------

Making a 16-invh pizz with the following toppings:
- pepperoni

Making a 12-invh pizz with the following toppings:
- mushroom
- green peppers
- extra cheese
-----------------导入模块中的特定函数-----------------

Making a 16-invh pizz with the following toppings:
- pepperoni

Making a 12-invh pizz with the following toppings:
- mushroom
- green peppers
- extra cheese
-----------------给导入模块中的特定函数起别名-----------------

Making a 16-invh pizz with the following toppings:
- pepperoni

Making a 12-invh pizz with the following toppings:
- mushroom
- green peppers
- extra cheese
-----------------给导入模块起别名-----------------

Making a 16-invh pizz with the following toppings:
- pepperoni

Making a 12-invh pizz with the following toppings:
- mushroom
- green peppers
- extra cheese
-----------------导入模块中的所有函数-----------------



 
#课后习题如下所示
#8-15
#test1
def print_models(unprinted_designs,completed_models):
    """模型打印每个设计,直到没有未打印的设计为止
        打印每个设计后,都将其移到列表completed_mode
        ls中
    """
    while unprinted_designs:
        current_desgion = unprinted_designs.pop()

        #模拟根据设计制作3D打印模型的过程
        print("Prining model: " + current_desgion)
        completed_models.append(current_desgion)

def show_completed_models(completed_model):
    """显示打印好的模型"""
    print("
The following modles have been printed:")
    for completed_model in completed_model:
        print(completed_model)
###############################
#test2
from test1 import *

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

print_models(unprinted_designs,completed_models)
show_completed_models(completed_models)

#输出结果如下所示:
Prining model: dodecahedron
Prining model: robot pendant
Prining model: iphone case

The following modles have been printed:
dodecahedron
robot pendant
iphone case
Prining model: dodecahedron
Prining model: robot pendant
Prining model: iphone case

The following modles have been printed:
dodecahedron
robot pendant
iphone case
原文地址:https://www.cnblogs.com/a404790696/p/11010440.html