python中的函数

目录

一、定义函数

二、传递实参

三、返回值

四、传递列表

五、传递任意数量实参

六、将函数存储在模块中

七、函数编写指南


一、定义函数

首先函数定义def + 函数名 +()+ :,函数定义后面的所有缩进体构成函数体,三引号内的文本为文本字符串——描述函数是做什么,print( )是函数体内唯一一行代码,因此greet_user()只做了一项工作:打印Hello!

函数调用让python执行函数的代码,要调用函数只需要指定函数名 +()函数调用的方式:a.函数名+(),()内可以有内容;b.将函数名+()赋值给一个变量,再打印变量。

def greet_user():            #函数定义
	"""显示简单的字符串"""
	print("Hello!")
greet_user()
Hello!

1.向函数传递信息

在函数定义def greet_user( )的括号中添加username,可让函数接受你给username指定的任何值

def greet_user(username):
	print(f"Hello, {username}.")
greet_user('sarah')
Hello, sarah.

2.实参和形参

前面定义函数greet_user( )时,变量username是形参,值‘sarah'是实参形参是可以被顶替的幌子,存在于定义参数中的括号和函数体中;实参是实在可打印出来的,存在于函数调用。形参不需要打引号,实参需要打引号。

在greet_user('jesse')中,将实参’jesse’传递给了函数greet_user(),这个值被赋给了形参username。注意:有时形参和实参不分。

二、传递实参

函数定义中可能包含多个形参,因此函数调用中可能也包括多个实参。向函数传递实参的方式有很多,可使用位置参数,要求形参和实参的顺序相同;也可使用关键字参数,其中每个实参都由变量名和值组成。

1.位置实参

调用函数时,python必须函数调用中的每个实参关联到函数定义中的一个形参。最简单的关联方式是基于实参的顺序,这种关联方式被称为位置实参

函数定义表明需要一种动物类型和一个名字。在调用函数时也需要按顺序提供一种动物类型和一个名字。

def describe_pet(animal_type,pet_name):
	print(f"I have a {animal_type}.")
	print(f"My {animal_type}'s name is {pet_name}.")
describe_pet('hamaster','harry')   #将实参hamaster关联到形参animal_type,将实参harry关联到形参pet_name
I have a hamaster.
My hamaster's name is harry.

多次调用函数:可根据需要调用函数任意次,python将按照顺序将函数调用中的实参关联到函数定义中相应的形参。位置实参的顺序很重要

def describe_pet(animal_type,pet_name):
	print(f"I have a {animal_type}.")
	print(f"My {animal_type}'s name is {pet_name}.")
describe_pet('hamaster','harry')
describe_pet('dog','willie')
I have a hamaster.
My hamaster's name is harry.
I have a dog.
My dog's name is willie.

2.关键字实参

关键词实参是传递给函数的名称值对。在实参中将名称和值关联起来,所有向函数传递实参时不会混淆。使用关键词实参时,一定要准确指定函数定义中的形参名。

def describe_pet(animal_type,pet_name):
	print(f"I have a {animal_type}.")
	print(f"My {animal_type}'s name is {pet_name}.")
describe_pet(animal_type = 'hamaster',pet_name = 'harry')   #形参不需要打引号,实参需要打引号
I have a hamaster.
My hamaster's name is harry.

3.默认值

编写函数时,可以给形参指定默认值。若调用函数时,指定了实参,python将使用指定的实参值;否则,将使用形参的默认值。默认值出现在定义函数中,且要放在后面

给animal_type指定了默认值,在调用函数时,如果没有给animal_type指定实参,将使用默认值dog。所以函数调用中只包含宠物的名字,然而python依旧将实参视为位置参数,这个实参将关联到定义中的第一个形参。故可以在函数调用时,只提供小狗的名字。

def describe_pet(pet_name,animal_type = 'dog'):
	print(f"I have a {animal_type}.")
	print(f"My {animal_type}'s name is {pet_name}.")
describe_pet(pet_name = 'willie')
#等价于 describe_pet('willie')
I have a dog.
My dog's name is willie.

4.等效的函数调用

def describe_pet(pet_name,animal_type = 'dog'):
	print(f"I have a {animal_type}.")
	print(f"My {animal_type}'s name is {pet_name}.")
describe_pet('willie')
describe_pet(pet_name = 'willie')
describe_pet('harry','hamster')
describe_pet(pet_name = 'harry',animal_type = 'hamaster')
describe_pet(animal_type = 'hamaster',pet_name = 'harry')

5.避免实参错误

若实参多于或少于函数完成工作所需的信息时,将出现实参不匹配错误

def describe_pet(pet_name,animal_type = 'dog'):
	print(f"I have a {animal_type}.")
	print(f"My {animal_type}'s name is {pet_name}.")
describe_pet()
TypeError: describe_pet() missing 1 required positional argument: 'pet_name' #指出函数调用少了1个实参,并指出了相应的实参名称

三、返回值

函数并非总是显示输出,还可以处理数据。函数返回的值称为返回值。在函数中,可使用return语句值返回到调用函数的代码行

在函数中,两种打印方式:a.函数体中包括print,函数调用中直接用函数名+();b.函数体中不包括print,是变量的等式,函数体中要return,函数调用中包括print。

1.返回简单值

调用返回值函数时,需提供一个变量,以便将返回的值赋给它。原本只需要输入print("Jimi Hendrix")就可输出,但在需要分别存储大量名和姓的大型程序中,像get_formatted_name()这样的函数非常有用。return语句可将值返回到调用函数的代码行,实质就是调用函数体中有用的那一行full_name = f"{first_name} {last_name}" 再根据其设定实参。return后面都要跟变量,而非函数名

def get_formatted_name(first_name,last_name):
	full_name = f"{first_name} {last_name}"
	return full_name.title()
musician = get_formatted_name('jimi','hendrix')   #将返回值赋给变量
print(musician) 
Jimi Hendrix
def get_formatted_name(first_name,last_name):
	full_name = f"{first_name} {last_name}"
	print(f"{full_name.title()}")
get_formatted_name('jimi','hendrix')  

2.让实参变成可选的(将可选的形参设为空字符串+if语句)

让实参变成可选,可以使得只在必要时提供额外信息,使用默认值来让实参变成可选的。

def get_formatted_name(first_name,middle_name,last_name):
	full_name = f"{first_name} {middle_name} {last_name}"
	return full_name.title()
musician = get_formatted_name('john','lee','hooker')
print(musician)
John Lee Hooker

并非所有人都有中间名,若只提供名和姓,它将不能正确运行,为了让中间名可选,可给形参指定一个空的默认值。将形参middle_name的默认值设为一个空字符串,并将其移到形参列表末尾

def get_formatted_name(first_name,last_name,middle_name = ""):  #可选形参
	if middle_name:    #如果middle_name为True                   #if语句
		full_name = f"{first_name} {middle_name} {last_name}"
	else:
		full_name = f"{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):
	person = {'first':first_name,'last':last_name}   #创建字典
	return person                                    #返回字典
musician = build_person('jimi','hendrix')
print(musician)
{'first': 'jimi', 'last': 'hendrix'}

在字典中添加可选形参。将可选形参的默认值设为特殊值None或空字符串(表示变量没有值)。可将None视为占位符,在条件测试中,None相当于False,如果函数调用中包含形参的值,这个值将存储在字典中。

def build_person(first_name,last_name,age = None):   #可选形参
	person = {'first':first_name,'last':last_name}   #创建字典,可选形参先不用加入字典
	if age:                                          #对可选形参进行管理,if语句
		person['age'] = age                          #若需要可选形参,再在字典中添加键值对
	return person                                    #返回字典
musician = build_person('jimi','hendrix',age = 21)
print(musician)
{'first': 'jimi', 'last': 'hendrix', 'age': 21}

4.结合使用函数和while循环

可将函数同前面介绍的任何python结构结合起来。

def get_formatted_name(first_name,last_name):
	full_name = f"{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(f"\nHello,{formatted_name}!")
Please tell me your name,
(enter 'q' at any time to quit)
First name: zuo
Last name: xin

Hello,Zuo Xin!

Please tell me your name,
(enter 'q' at any time to quit)
First name: q

注意:所有交互式代码都可以用文本编辑器编写,在终端上直接运行。运行方法参照第一篇博文(f: —— cd 路径 —— dir查看内容——python +文件)

四、传递列表

将列表传递给函数后,函数就能直接访问其内容。

def greet_users(names):
	for name in names:
		msg = f"Hello,{name.title()}."
		print(msg)
usernames = ['hannah','ty','margot']         #定义了一个用户列表usernames
greet_users(usernames)                       #调用函数,并将列表传递给了它
Hello,Hannah.
Hello,Ty.
Hello,Margot.

1.在函数中修改列表

列表传递给函数后,函数就可对列表进行修改,且是永久性的,所有可以高效的处理大量数据。需要打印的设计放在一个列表中,打印后移到另一个列表中,不适用函数的情况下的代码:

unprinted_designs = ['phone case','robot pendant','dodecahedron']
completed_models = []
while unprinted_designs:
	current_design = unprinted_designs.pop()
	print(f"Printing model:{current_design}")
	completed_models.append(current_design)
print("\nThe following models have been printed:")
for completed_model in completed_models:
	print(completed_model)
Printing model:dodecahedron
Printing model:robot pendant
Printing model:phone case

The following models have been printed:
dodecahedron
robot pendant
phone case

为重新组织这些代码,可编写两个函数。第一个函数负责处理打印设计的工作,第二个概述打印哪些设计。使用函数的组织更为有序,大部分的工作代码移到了两个函数中,让主程序更容易理解,同时程序更容易拓展和维护,若需对打印代码进行修改,只需改一次。

def print_models(unprinted_designs,completed_models):
	while unprinted_designs:
		current_design = unprinted_designs.pop()
		print(f"Printing {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 = ['dodecahedron','robot pendant','phone case']
completed_models = []
print_models(unprinted_designs,completed_models)  #由于已经定义了两个函数,只需调用它们并传入正确的实参即可。
show_completed_models(completed_models)
Printing phone case
Printing robot pendant
Printing dodecahedron

The following models have been printed:
phone case
robot pendant
dodecahedron

每个函数都应只负责一项具体的任务,可以在一个函数中调用另一个函数。编写函数时发现执行的任务太多,可尝试将这些代码划分到两个函数。

2.禁止函数修改列表

即便打印好了所有设计,也要保留原来的未打印的设计列表,以供备案。但由于将所有的设计都移出了unprinted_designs,这个列表变成了空的,原来的列表没有了。为解决这个问题,可向函数传递列表的副本而非原件。用切片表示法创建列表。

print_models(unprinted_designs[:],completed_models)

虽然向函数传递列表的副本可保留原始列表的内容,但除非有充分理由,否则将原始列表传递给函数,因为让函数使用现成列表可避免花时间和内存创建副本,提高效率,尤其是处理大型列表。

五、传递任意数量实参

形参名*toppings中的*星号让Python创建一个名为toppings的空元组,并将收到的所有值都封装到这个元组中

def make_pizza(*toppings):
	"""概述要制作的比萨"""
	print("\nMaking a pizza with the following toppings: ")
	for topping in toppings:
		print(f"-{topping}")
make_pizza("pepperoni")
make_pizza("mushrooms","green pepers","extra cheese")
Making a pizza with the following toppings: 
-pepperoni

Making a pizza with the following toppings: 
-mushrooms
-green pepers
-extra cheese

结合使用位置实参和任意数量实参:函数接受不同类型的实参,必须在函数定义中将接纳任意数量实参的形参放在最后。Python将收到的第一个值赋给形参size,并将其他所有值都存储在元组toppings中。形参名*args,它也收集任意数量的位置实参

def make_pizza(size,*toppings):
	"""概述要制作的比萨"""
	print(f"\nMaking a {size}-inch pizza with the following toppings: ")
	for topping in toppings:
		print(f"-{topping}")
make_pizza(16,"pepperoni")
make_pizza(22,"mushrooms","green pepers","extra cheese")
Making a 16-inch pizza with the following toppings: 
-pepperoni

Making a 22-inch pizza with the following toppings: 
-mushrooms
-green pepers
-extra cheese

使用任意数量的关键字实参,形参**user_info中的**两个星号让Python创建一个名为user_info的空字典,形参名**kwargs,它用于收集任意数量的关键字实参。

def build_profile(first,last,**user_info):
    """创建字典,包含我们知道的用户一切信息"""
	user_info['first_name'] = first           #将名和姓加入了字典user_info中,字典添加键值对与函数参数结合
	user_info['last_name'] = last
	return user_info
user_profile = build_profile('albert','einstein',location = 'princeton',field = 'physics')
print(user_profile)
{'location': 'princeton', 'field': 'physics', 'first_name': 'albert', 'last_name': 'einstein'}

六、将函数存储在模块中

将函数存储在称为模块的独立文件中,再将模块导入到主程序中,使用import语句

隐藏程序代码的细节,将重点放在程序的高层逻辑上;重用;共享;使用其他程序员编写的函数库

要让函数是可导入的,得先创建模块。模块是扩展名为.py的文件,包含要导入到程序中的代码。

1.导入整个模块

pizza.py文件中只有函数make_pizza( ),在pizza.py所在的目录中创建makeing_pizzas.py的文件

def make_pizza(size,*toppings):
	"""概述要制作的比萨"""
	print(f"\nMaking a {size}-inch pizza with the following toppings: ")
	for topping in toppings:
		print(f"-{topping}")

要调用被导入模块中的函数, 指定模块名和函数名,中间用句点分割

import pizza
pizza.make_pizza(16,'pepperoni')
pizza.make_pizza(22,'mushrooms','green pepers','extra cheese')
Making a 16-inch pizza with the following toppings: 
-pepperoni

Making a 22-inch pizza with the following toppings: 
-mushrooms
-green pepers
-extra cheese

2.导入特定函数

调用函数时无需使用句点,调用时只需要指定函数名

from pizza import make_pizza
make_pizza(16,'pepperoni')
make_pizza(22,'mushrooms','green pepers','extra cheese')

3.使用as给函数指定别名

导入的函数名称可能与程序中的名称相冲突,或函数名称太长,可用别名:函数另一个名称,外号

from pizza import make_pizza as mp
mp(16,'pepperoni')
mp(22,'mushrooms','green pepers','extra cheese')

4.使用as 给模块命名

import pizza as p
p.make_pizza(16,'pepperoni')
p.make_pizza(22,'mushrooms','green pepers','extra cheese')

5.导入模块中所有函数

用星号(*)运算符可让Python导入模块中的所有函数。因导入了每个函数,无需句点表示。但尽量不要使用这种方法,若模块中有函数的名称与当前项目中使用的名称相同,会出错。

from pizza import *
make_pizza(16,'pepperoni')
make_pizza(22,'mushrooms','green pepers','extra cheese')

要么只导入需要的函数,要么导入整个模块用句点表示法

七、函数编写指南

应给函数指定描述性名称,且只在其中使用小写字母和下划线。

注释应紧跟在函数定义后面,并采用文档字符串格式。

给形参指定默认值时,等号两边不要有空格。

若形参很多,使函数定义的长度超过了79字符,可在函数定义中输入左括号后按回车键,并在下一行按两次Tab键,将形参列表和只缩进一层的函数体区分开来。

程序或模块包含多个函数,可使用两个空行将相邻的函数分开,这样将更容易知道前一个函数在什么地方结束。

import语句都应放在文件开头,除非开头为注释。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值