定义函数
函数是带名字的代码块,用于实现具体的工作。在以后遇到相同的处理可以直接调用,不用重新编码。函数一般存储在称为模块的独立文件中。
def greet_user():
"""显示简单的问候语"""
print('Hello!')
greet_user()
使用关键字 def 来告诉python我要定义一个函数。这就是函数定义,指出函数名,以及需要的参数,最后冒号结尾。
三引号里面的文本被称为文档字符串的注释,描述函数主要是来做什么的。后面的缩进行,就是函数体。
要调用函数可以依次指定函数名和括号里边需要的信息,这里不需要任何信息。
向函数传递信息
其实稍微修改一下函数,就可以给函数传递函数信息。
def greet_user(username):
print("Hello," + username.title() + '!')
greet_user('jesse')
Hello Jesse!
实参和形参
在函数greet_user()中,变量username就是一个形参----函数完成其工作需要的一项信息。'jesse’就是一个实参。实参是调用函数时传递给函数的信息。
传递实参
鉴于函数定义中可能包含多个形参,因此函数调用也可能包含多个实参。避免传递混乱,规定了多重方法,有位置实参,这要求形参和实参位置相同,还有关键字实参,每个实参都由变量名和值组成,还可以使用列表和字典。
位置实参
在函数调用中,每个实参都需要关联到函数定义中的一个形参。因此最简单的关联方式就是基于实参的顺序。这种关联方式被称为位置实参。
def describle_pet(pet_type,pet_name):
"""显示宠物的信息"""
print("My" + animal_type + "'s name is " + pet_name.title() + '.')
describle_pet('hamster','harry')
describle_pet('dog','willie')
调用函数多次都可以,想要描述另外的宠物,重新调用就好了,这样程序会更加高效。而且位置实参的顺序很重要,我们一定要和形参关联起来,一对一,不能填错,否则会出现形参和实参不匹配的问题。
关键字实参
关键字实参是传递给函数名称–值对。直接在实参中将名称和值关联起来了,因此传递的实参不会混淆,这样不用考虑形参的位置,更加直观的看出每个值的用途。
def describle_pet(pet_type,pet_name):
"""显示宠物的信息"""
print("My" + animal_type + "'s name is " + pet_name.title() + '.')
describle_pet(pet_type='hamster',pet_name='harry')
describle_pet(pet_name='harry',pet_type='hamster')
调用是明确指定各个实参对应的形参,这样就算交换顺序也不会影响函数获取的值。只是要注意形参名别写错了。
默认值
编写函数时,可以给每个形参指定默认值。如果在调用函数的时候提供了实参,python将使用实参值。否则,将会使用形参的默认值,这样函数调用中省略实参,这样也不会报错。
def describle_pet(pet_name,pet_type='dog'):
"""显示宠物的信息"""
print("My" + animal_type + "'s name is " + pet_name.title() + '.')
describle_pet(pet_name='willie')
describle_pet('willie')
请注意我调换了一下name和type的位置,因为在调用的时候,有默认值,实参只传递一个,但是还是会当做位置实参来处理,这样会导致传参错误,所以有默认值的情况下,形参列表中先列没有默认值的形参,这样会避免出错。
等效的函数调用
其实上面例子我已经展示过了等效函数调用,用位置实参和关键字实参传参,最后结果都是一样的。那种调用方式都一样,只要函数调用能生成你希望的输出。
避免实参错误
在编程中如果出现实参不匹配的错误,检查自己的代码,一般都是有bug的。
标题返回值
函数并非总是之间显示输出,它可以处理一些数据,并返回一个或者一组值。函数返回的值被称为返回值。在函数中,可使用return语句将值返回到调用函数的代码行。返回值让你能够将程序移到函数里面,这样可以方便使用。
返回简单值
def get_name(first_name,last_name):
"""返回整洁的姓名"""
full_name = first_name + ' ' + last_name
return full_name.title()
musician = get_name('jimi','hendrix')
print(musician)
Jimi Hendrix
让实参变成可选的
def get_formatted_name(first_name,last_name,middle_name=''):
"""返回整洁的名字"""
if middle_name:
full_name = first_name + ' ' + last_name + ' ' + middle_name
else:
full_name = first_name + ' ' + last_name
return full_name.title()
musician = get_formatted_name('jimi','hendrix')
musician = get_formatted_name('jimi','hendrix','lee')
可以给形参middle_name指定一个默认值–空字符串,用户没有传递实参就不使用它,传递实参就会使用,并且位置要注意放到后面,防止参数错误。
返回字典
函数可以返回任何类型的值,包括列表和字典等复杂的数据结构。
def build_person(first_name,last_name):
"""返回一个字典,其中包含一个人的信息"""
person = {'first':first_name,'last':last_name}
return person
musician = build_person('jimi','hendrix')
print(musician)
{'first':'jimi','last':'hendrix'}
函数build_person()接收名和姓,并将这些值封装到字典中。
结合使用函数和while循环
函数可以和其他python结构结合起来使用。
def get_name(first_name,last_name):
"""返回整洁的姓名"""
full_name = first_name + ' ' + lsat_name
return full_name.title()
while True:
f_name = input("First name: ")
if f_name == "q":
break
l_nmae = input("Last name: ")
print("If you want to quit please input 'q'!")
formatted_name = get_name(f_name,l_name)
传递列表
def greet_user(names)
"""向列表中的每位用户都发出简单问候"""
for name in names:
print("Hello" + ' ' + name.title() + '!')
username = ['bob','jmmi','caven']
greet_users(usernames)
在函数中修改列表
将列表传递给函数之后,函数就可以对其修改。在函数中对列表的做的修改都是永久性的。
传递任意数量的实参
def make_pizza(*toppings):
"""打印顾客点的所有配料"""
print(toppings)
make_pizza('pepperoni')
make_pizza('mushroom','green peppers','extra cheese')
('pepperoni',)
('mushroom','green peppers','extra cheese')
形参名*toppings中的星号让python创建一个名为toppings的空元组,并将接收到的所有值都装到这个元组中。python把实参封装到一个元组中,接收一个参数也这样。
结合使用位置实参和任意数量实参
要让函数接收不同类型的实参,必须在函数定义中将接纳任意数量实参的形参让在最后。python先匹配位置实参和关键字实参,再讲剩下的实参都收集到最后一个形参中。所以任意数量形参只能放后面。
def make_pizza(size,*toppings):
print("Make a pizza is " + str(size) + "inch." )
for topping in toppings:
print("- " + topping)
make_pizza(16,'pepperoni')
make_pizza(12,'mushrooms','green peppers','extra cheese')
你可以尝试调换尺寸和馅的位置,结果自己想。
使用任意数量的关键字实参
def build_profile(first,last,**user_info):
profile = {}
profile['first_name'] = first
profile['last_nmae'] = 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的空字典,并将收到的所有名称-值对封装到这个字典中。
将函数存储在模块中
将函数存储在被称为模块的独立文件中,再将模块导入到主程序中。import语句允许在当前运行的程序文件中使用模块的代码。
导入整个模块
模块是扩展名为.py的文件,其中包含了要导入到程序中的代码。
def make_pizza(size,*toppings):
print("Make a pizza is " + str(size) + "inch." )
for topping in toppings:
print("- " + topping)
我们创建一个包含函数make_pizza()的模块。接下来在pizza.py的目录所在创建另外一个名为making_pizzas.py的文件,这个文件导入刚刚那个创建的模块,然后调用make_pizza()。
import pizza
pizza.make_pizza(16,'pepperoni')
pizza.make_pizza(12,'mushrooms','green peppers','extra cheese')
python读取这个文件时,代码行import pizza 让python打开文件pizza.py,并将所有函数复制到这个程序中,但你看不到复制的代码和过程,因为这是幕后做的。
要使用模块中的函数:
module_name.function_name()
导入特定的函数
导入模块中特定的函数,导入语法:
from module_name import function_name
用逗号分隔函数名,可根据需要从模块中导入任意数量的函数:
from module_name import function_0,function_1,function _2
对于前面的making_pizzas.py,如果只想导入要使用的函数,代码将类似于下面这样
from pizza import make_pizza
make_pizza(16,'pepperoni')
使用这种语法,调用函数不需要使用句点。因为我们显示的调用了make_pizza().
使用as给函数指定别名
如果要导入的函数名和现有的程序中的名称有冲突,或者函数的名称太长,可以指定一个独一无二的别名,类似于外号。
from pizza import make_pizza as mp
mp(16,'pepperoni')
语法:
from module_name import function_name as fn
使用as给模块指定别名
语法:
import module_name as mn
导入模块中的所有函数
使用 * 星号 可以让python导入模块中的所有函数:
from pizza import *
make_pizza(16,'pepperoni')
一般不要使用这种方法,容易引起覆盖本程序的名称。
本章总结
在这章我们学习了如何编写函数,以及传递实参,如何使用关键字实参,位置实参,以及接受任意数量的实参;显示输出的函数和返回值的函数;如何将函数同列表,字典,if,while循环结合起来使用。如何将程序存储在被称为模块的独立文件中,让程序文件更简单,更易于理解。