函数
实参和形参
形参是函数完成其工作所需的一项信息;实参是在调用函数时传递给函数的信息。
一.传递实参
位置实参:要求实参的顺序和形参的顺序相同。
关键字实参:其中每个实参都由变量名和值组成。
还可以使用列表和字典。
1.位置实参
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')
I have a hamster.
My hamster's name is Harry.
I have a dog.
My dog's name is Willie.
2.关键字实参
是传递给函数的名称-值对。直接在实参中将名称和值关联起来,向函数传递实参时不会混淆。
无需考虑函数调用中的实参顺序,还清楚的指出了函数调用中各个值的用途。
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')
I have a hamster.
My hamster's name is Harry.
I have a hamster.
My hamster's name is Harry.
调用函数时,明确指出各个实参对应的形参。
3.默认值
编写函数时,可给每个形参指定默认值。
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 = 'harry')
describe_pet('harry')#等效的函数调用
describe_pet(pet_name='harry',animal_type='hamster')
I have a dog.
My dog's name is Harry.
I have a dog.
My dog's name is Harry.
I have a hamster.
My hamster's name is Harry.
使用默认值时,在形参列表中必须先列出没有默认值的形参,再列出有默认值的实参,python才能正确解读位置实参。
等效函数调用
def describe_pet(pet_name,animal_type=‘dog’):
任何情况下,都必须给pet_name提供实参,指定时可以使用位置方式,也可以使用关键字方式。
4.让实参变成可选的
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
first_name,last_name是必须提供的形参,函数定义时首先列出来,middle_name是可选的,函数定义时最后列出该形参。
5.返回字典
def build_person(first_name,last_name,age=''):
person={first_name:'first_name',last_name:'last_name'}
if age:
person['age']=age
return person
#musician=build_person('jimi','hendrix',23)
musician=build_person('jimi','hendrix',age=23)
print(musician)
musician=build_person('jimi','hendrix')
print(musician)
{'jimi': 'first_name', 'hendrix': 'last_name', 'age': 23}
{'jimi': 'first_name', 'hendrix': 'last_name'}
age是可选形参,默认值设为空字符串。
6.结合使用函数和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:')
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 + "!")
Please tell me your name:
(Enter "q" at any time to quit.)
First name:eric
Last name:matthes
Hello, Ericmatthes!
Please tell me your name:
(Enter "q" at any time to quit.)
First name:q
while循环让用户输入姓名:依次提示用户输入名和姓
7.传递任意数量的形参
有时候预先不知道函数需要接受多少个实参,python允许函数从调用语句中收集任意数量的形参。
def make_pizza(*toppings):
print("\nMaking a pizza with the following toppings:")
print(toppings)
for topping in toppings:
print("- " + topping)
make_pizza('pepperoni')
make_pizza('mushrooms','green prppers','extra cheese')
```python
Making a pizza with the following toppings:
('pepperoni',)
- pepperoni
Making a pizza with the following toppings:
('mushrooms', 'green prppers', 'extra cheese')
- mushrooms
- green prppers
- extra cheese
形参名*toppings中的星号让Python创建一个名为toppings的空元组,并将收到的所有值都封装到这个元组中。
8.结合使用位置实参和任意数量实参
def make_pizza(size,*toppings):
print("\nMaking a " + str(size) + "-inch pizza with the following topping:")
for topping in toppings:
print("-" + topping)
make_pizza(16,'pepperoni')
make_pizza(12,'mushroom','green peppers','extra cheese')
Making a 16-inch pizza with the following topping:
-pepperoni
Making a 12-inch pizza with the following topping:
-mushroom
-green peppers
-extra cheese
python将收到的值存储在形参size中,其他所有值存储在元组toppings中。
9.使用任意数量的关键字实参
将函数编写成能够接受任意数量的实参
def bulid_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=bulid_profile('albert','einstein',location='princeton',field='physics')
print(user_profile)
{'first_name': 'albert', 'last_name': 'einstein', 'location': 'princeton', 'field': 'physics'}
形参**user_info中的两个星号让python创建了一个名为user_info的空字典,并将收到的所有名称-值对都封装到这个字典中。
二.传递列表
假设有一个用户列表,要问候其中的每位用户。
将一个名字列表传递给一个名为greet_users()的函数。
def greet_users(names):
for name in names:
msg = "Hello, " + name.title() + "!"
print(msg)
usernames=['hannah','ty','margot']
greet_users(usernames)
Hello, Hannah!
Hello, Ty!
Hello, Margot!
1.在函数中修改列表
将列表传递给函数后,函数就可以对其修改,函数中对这个列表所做的任何修改都是永久性的。
def print_models(unprint_designs,completed_models):
while unprint_designs:
current_design=unprint_designs.pop()
print("Printing model: " + current_design)
completed_models.append(current_design)
def show_complete_models(completed_models):
print("\nThe following models have been printed:")
for completed_model in completed_models:
print(completed_model)
unprint_designs=['iphone case','robot,'pendant','dodecahedron']
completed_models=[]
print_models(unprint_designs,completed_models)
show_complete_models(completed_models)
print(unprint_designs)
Printing model: dodecahedron
Printing model: robot pendant
Printing model: iphone case
The following models have been printed:
dodecahedron
robot pendant
iphone case
[]
每个函数都只应负责一项具体的工作。第一个函数打印每个设计,第二个函数显示打印好的模型。
2.禁止函数修改列表
如要要在打印所有设计后,也要保留原来的为打印的设计列表,以供备案。
在调用函数时,用切片法[:]创建列表的副表,函数print_models()依然可以完成工作,但是使用的是列表unprint_designs的副本,而不是其本身。
这样可以保留原始列表的内容。
print_models(unprint_designs[:],completed_models)
print(unprint_designs)
['iphone case', 'robot pendant', 'dodecahedron']
三.将函数存储在模块中
将函数存储在被称为模块的独立文件中,再将模块导入到主程序中。
模块是扩展名为.py的文件
导入模块
import module_name
调用被导入的模块中的函数
import module_name
module_name.function_name()
导入模块中特定函数
from module_name import function_name
from module_name import function_0,function_1,function_2
使用这种语法,调用函数时就无需使用句点。
使用as给函数指定别名
from module_name import function_name as fn
使用as 给模块指定别名
import module_name as mn
导入模块中的所有函数
from module_name import *
最好不要采用这种导入方法,如果模块中有函数的名称和项目中使用的名称相同,可能导致意想不到的结果。
最佳做法是只导入需要使用的函数,要么导入整个模块并使用句点表示法。
四.函数编写指南
应该给函数指定描述性名称,且只在其中使用小写字母和下划线,模块命名也遵循上述约定。
每个函数应该包含简要地阐述其功能的注释,该注释紧跟在函数定义后面,并采用文档字符串格式。
给形参指定默认值时,等号两边不要空格。
def function_name(parameter_0,parameter_1=‘default value’)
调用关键字实参,也遵循这种约定。
function_name(value_0,parameter_1=‘value’)
如果函数定义中的形参太多导致函数定义的长度超过了79字符,在函数定义中输入左括号后按回车键,并在下一行按两次Tab键,从而将形参列表和只缩进一成的函数体区分开来。
def function_name(
parameter_0,parameter_1,parameter_2,
parameter_3,parameter_4,parameter_5):
function_body...
程序或者模块包含多个函数时,可使用两个空行将相邻的函数分开。
所有的import语句都应该放在文件开头。