函数的基本概念
def greet_user(username): print("Hello, " + username.title() + "!") greet_user('jesse')
输出为:
Hello, Jesse!
这是一个比较简单的函数。其中第一行叫做函数定义,它向Python指出了函数名,还在括号中包含了这个函数为完成其任务所需要的信息,这些参量被称作形参。紧跟在定义语句后面的所有缩进行构成了函数体。
第四行是函数调用,它让Python执行函数的代码。括号内的参量被称作实参,这个值在调用函数被储存在形参中,为函数完成对应工作提供必要信息。
传递实参的几种方式
1、位置实参
按形参的排列顺序,依次给出对应的实参。
def describe_pet(animal_type, pet_name): print("I have a " + animal_type + ".") print("My " + animal_type + "'s name is " + pet_name.title() + ".") describe_pet('hamster', 'harry')
输出为:
I have a hamster. My hamster's name is Harry.
2、关键字实参
关键字实参是传递给函数的名称-值对,在实参中直接将名称和值关联起来,因此向函数传递实参时不会混淆。
当使用关键字实参时,可随意改变不同实参间的排列顺序,而传递的结果不变(只要不改变名称-值对应关系)。
def describe_pet(animal_type, pet_name): print("I 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')
3、给定默认值
定义函数时,可为每个形参指定默认值。当调用函数时没有给出这些形参对应的实参时,它们会默认将各自的默认值作为实参运行;当给出对应实参时,则会使用这些实参运行。
def describe_pet(pet_name, animal_type = 'dog'): print("I have a " + animal_type + ".") print("My " + animal_type + "'s name is " + pet_name.title() + ".") describe_pet(pet_name = 'willie')
#注意:给定默认值的形参要排在后面,没有给定默认值的排在前面,否则编译器会报错。
复杂的传参问题
1、传递任意数量的参量
当预先不知道函数需要多少个参量时使用。
def make_pizza(*toppings):
'''打印所有配料'''
print("
Making a pizza with the following toppings:")
for topping in toppings:
print("- " + topping)
make_pizza('pepperoni')
make_pizza('mushrooms', 'green peppers', 'extra cheese')
输出为:
Making a pizza with the following toppings:
- pepperoni
Making a pizza with the following toppings:
- mushrooms
- green peppers
- extra cheese
其中形参名*toppings中的星号*让Python创建一个名为toppings的空元组,并将接收到的所有值都装进这个元组中。
2、结合使用位置实参和任意数量实参
如果要让函数接受不同类型的实参,必须在函数定义中将接纳任意数量实参的形参放在最后。Python先匹配位置实参和关键字实参,再将余下的实参都收集到最后一个形参中。
def make_pizza(size, *toppings): '''概述要制作的披萨''' print(" Making 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')
输出为:
Making a 16-inch pizza with the following toppings: - pepperoni Making a 12-inch pizza with the following toppings: - mushrooms - green peppers - extra cheese
3、使用任意数量的关键字实参
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 = 'prinston', field = 'physics') print(user_profile)
输出为:
{'first_name': 'albert', 'last_name': 'einstein', 'location': 'prinston', 'field': 'physics'}
其中形参名**user_info中的两个星号让Python创建一个名为user_info的空字典,并将接收到的名称-值对都封装在这个字典中。在这个函数中,可以像访问其他字典那样访问user_info中的名称-值对。
返回值
函数返回主程序的值被称为返回值。可使用return语句将值返回到调用函数的代码行,从而简化主程序。
1、返回简单值
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)
输出为:
Jimi Hendrix
2、让实参变成可选的
当不是所有情况都需要用到某些实参时,可通过给它们对应的形参指定一个默认值——空字符串的方式,让这个实参变成可选的。
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() musician = get_formatted_name('jimi', 'hendrix') print(musician) musician = get_formatted_name('john', 'hooker', 'lee') print(musician)
输出为:
Jimi Hendrix
John Lee Hooker
3、返回字典
返回值是一个字典的情形。
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 = 27) print(musician)
输出为:
{'first': 'jimi', 'last': 'hendrix', 'age': 27}
向函数传递列表
1、简单的列表传递
将列表作为参量传递给函数。
def greet_users(names): for name in names: message = "Hello " + name.title() + "!" print(message) usernames = ['hannah' , 'ty' , 'margot'] greet_users(usernames)
输出为:
Hello Hannah!
Hello Ty!
Hello Margot!
2、在函数中修改列表
改写以下程序:
'''创建一个列表,其中包含一些要打印的设计''' unprinted_designs = ['iphone case', 'robot pendant', 'dodecahedron'] completed_models = [] '''打印每个设计,直到没有未打印的设计为止''' '''打印每个设计后,都将其移到列表unprinted_models中''' while unprinted_designs: current_design = unprinted_designs.pop() print("Printing model: " + current_design) completed_models.append(current_design) '''显示打印好的所有模型''' print(" The following models have been printed:") for completed_model in completed_models: print(completed_model)
该程序输出为:
Printing model: dodecahedron
Printing model: robot pendant
Printing model: iphone case
The following models have been printed:
dodecahedron
robot pendant
iphone case
引入两个函数来实现相同的功能:
def print_models(unprinted_designs, completed_models): '''打印每个设计,然后将它们移至列表completed_models中''' while unprinted_designs: current_design = unprinted_designs.pop() print("Printing model: " + current_design) completed_models.append(current_design) def show_completed_models(completed_models): '''显示打印好的所有模型''' print(" The 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)
3、保留原有列表
可通过向函数传递切片表示法([ : ])所创建的列表的副本而不是原件的方式,使函数中的相关修改只影响列表的副本而不是原件,从而保留原来的列表。
'''传递格式如下''' function_name(list_name[ : ]) '''例如''' print_models(unprinted_designs[ : ], completed_models)
模块
将函数存储在被称为模块的独立文件中,再将模块导入到主程序中。使用import语句可在当前运行的程序文件中使用模块中的代码。
使用模块可以让你把重点放在程序的高层逻辑上,还能让你在其他程序中使用该程序中的函数。
1、创建模块
模块是扩展名为.py的文件,包含想要导入到其他程序中的函数代码,如:
def make_pizza(size, *toppings): '''概述要制作的披萨''' print(" Making a " + str(size) + "-inch pizza with the following toppings:") for topping in toppings: print("- " + topping) '''将上面的代码保存在名为pizza.py的文件中'''
2、导入模块及调用模块中函数的几种方式
(1)导入整个模块
语法: import module_name module_name.function_name()
如:
import pizza
pizza.make_pizza(16, 'pepperoni')
Python读取这个文件时,代码行import pizza让Python打开文件pizza.py,并将其中所有函数都复制到这个程序中。使得在当前文件中,可以使用pizza.py中定义的所有函数。
当要导入的模块与程序中现有的名称冲突、过长或因其他原因不能使用原来的名称时,可以用as为其指定别名。
语法: import module_name as mn mn.function_name() 如: import pizza as p p.make_pizza(16, 'pepperoni')
(2)导入特定的函数
语法: from module_name import function_name function_name() 如: from pizza import make_pizza make_pizza(16, 'pepperoni')
与模块同理,函数也可以用as指定别名。
语法: from module_name import function_name as fn fn() 如: from pizza import make_pizza as mp mp(16, 'pepperoni')
(3)导入模块中所有函数
使用星号(*)运算符可让Python导入模块中的所有函数
语法: from module_name import * function_name() 如: from pizza import * make pizza(16, 'pepperoni')
然而,当使用非自己编写的大型模块时,最好不要采用这种方法。如果模块中有函数名称和当前程序中相同,可能出现意想不到的结果。所以除非情况特殊,最好使用前两种导入方法。
参考书籍:《Python编程:从入门到实践》
2020-07-14