本篇博客将系统的介绍Python函数,一个函数可以定义一项特定的任务,如果需要在程序中多次执行同一项任务,无需反复编写完成该任务的代码,只需调用执行该任务的函数即可。
目录
1.定义函数
- 简单函数
def greet_user():
print("hello!")
greet_user()
函数用关键字def定义,其中greet_user是函数名,其后的()必不可少(即使是空的),定义以:结尾。
:后的缩紧为函数体,描述函数要做什么。
调用函数直接输入greet_user().
- 向函数传递信息
在函数的()中可以设置参数,参数提供该函数需要的信息。
def greet_user(user_name):
print("hello!"+user_name.title())
greet_user('alice')
greet_user('bob')
- 实参和形参
函数括号中定义的参数,如之前的user_name称为形参;而调用函数时在括号中传入的参数为实参,如'alice'和'bob'。
在greet_user('alice')中将实参'alice'传递给函数greet_user(),这个值被存储在形参user_name中。
2.传递实参
函数定义中可以有多个形参,因此在调用时也可能传入多个实参。有以下几种向函数传递实参的方式:
- 位置实参
要求实参的顺序和形参必须相同,调用时一个实参关联一个形参,相应位置一一对应。
def describe_pet(animal_type,pet_name):
print("I have a "+animal_type+".")
print("Its name is "+pet_name+".")
describe_pet('dog','pp')
describe_pet('cat','mimi')
使用位置实参时,需要记住形参的顺序,顺序很重要,如果传入实参的顺序不对,可能会产生出人意料的结果或报错:
describe_pet('mini','cat')
此时和我们希望的正好相反。
- 关键字实参
关键字实参传入的是名-值对,传递实参时将形参名称和实参值进行关联。此时可以不用考虑实参的顺序问题,不需要记住形参的顺序,只需要知道有哪些形参就好了。推荐使用,可以减少不必要的麻烦/失误:
def describe_pet(animal_type,pet_name):
print("I have a "+animal_type+".")
print("Its name is "+pet_name+".")
describe_pet(animal_type='dog',pet_name='wangwang')
describe_pet(pet_name='wangwang',animal_type='dog')
- 默认值
编写函数时,可以为形参设置默认值。调用时如果为该形参传入了值,则使用传入的值,如果没有传,该形参就使用默认值。
对于没有设置默认值的形参,调用时必须传入实参(采用位置实参或关键字实参)。
定义函数时,注意有默认值的形参要在位置形参(没有默认值的形参)后面。
def describe_pet(pet_name,animal_type='dog'):
print("I have a "+animal_type+".")
print("Its name is "+pet_name+".")
describe_pet('wangwang')
describe_pet(pet_name='wangwang')
describe_pet(pet_name='mini',animal_type='cat')
- 等效的函数调用
在调用函数时可以使用位置实参、关键字实参或使用默认值,而且这些方式还可以混用,所以会有多种等价的函数调用方式,如下所示,都是i可以的:
def describe_pet(pet_name,animal_type='dog'):
print("I have a "+animal_type+".")
print("Its name is "+pet_name+".")
#一只名为 wangwang的小狗
describe_pet('wangwang')
describe_pet(pet_name='wangwang')
print("-------------------------------")
#一只名为mini的小猫
describe_pet('mini','cat')
#describe_pet(pet_name='mimi','cat') #位置实参必须在关键字实参前 否则报错
describe_pet('mini',animal_type='cat')
describe_pet(pet_name='mini',animal_type='cat')
describe_pet(animal_type='cat',pet_name='mini')
当函数形参比较多时,这种组合方式会越来越多。
注意当位置实参和关键字实参混合使用时,位置实参必须在关键字实参前面。
推荐统一使用关键字实参。
避免实参错误,传入的实参多于或少于函数定义的形参(默认形参除外)就会出现实参不匹配的错误。
3.返回值
Python函数可以返回一个值或一组值。
- 返回简单值
def get_format_name(first_name,last_name):
full_name = first_name+' '+last_name
return full_name.title()
fn = get_format_name(first_name='james',last_name='lebron')
print(fn)
- 让实参变为可选
def get_format_name(first_name,last_name,middle_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()
print(get_format_name(first_name='james',middle_name='a',last_name='leborn')) #使用关键字实参 不用关心顺序
print(get_format_name(first_name='james',last_name='leborn')) #可以不用传 使用默认值
- 返回字典
函数可以返回任意类型,包括列表、字典、元组等数据结构。
def build_person(first_name,last_name,age=''):
if age:
person = {'first':first_name,'last':last_name,'age':age}
else:
person = {'first':first_name,'last':last_name}
return person
print(build_person(first_name='james',last_name='le',age=27))
print(build_person(first_name='james',last_name='le'))
返回元组:
def A(a,b,c):
term1 = a+b+c
term2 = a*b*c
return term1,term2 #返回元组 省略了()
print(A(a=1,b=2,c=3))
print(A(a=2,b=2,c=2)[1]) #可以只取返回值中的某个值
- 结合使用函数和while循环
def get_format_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' to exit.")
f_name = input('first_name: ')
if f_name == 'q':
break
l_name = input('last_name: ')
if l_name == 'q':
break
print(get_format_name(first_name=f_name,last_name=l_name))
4.传递列表
有时候像函数传递列表会很有用,列表可能包含字符串、数字或更复杂的对象(列表,字典等)。
向函数传递列表,函数能直接访问他的内容。
def greet_users(names):
for name in names:
msg = 'hello,'+name.title()
print(msg)
user_names = ['alice','bob','dog']
greet_users(user_names)
- 在函数中修改列表
将列表传入函数,函数就可以对他进行修改,这种修改是永久性的。
def ZhuanYi(list1,list2):
#将list1中的元素转移到list2
while list1:
a = list1.pop()
print('current '+a)
list2.append(a)
l1 = ['alice','bob','dog']
l2 = []
print(l1)
print(l2)
ZhuanYi(list1=l1,list2=l2)
print("--------------------")
#l1,l2传入函数后 发生了变化 这种变化是永久的
print(l1)
print(l2)
如果传递列表,对形参进行修改,实参相应也被修改了。
如果传递数值变量,对形参修改,实参不会改变:
a = 5
def A(b):
b += 1
A(a)
print(a)
- 禁止函数修改列表
可以把列表的副本(列表的值)传给函数,此时形参被修改了,实参不会修改:
def ZhuanYi(list1,list2):
#将list1中的元素转移到list2
while list1:
a = list1.pop()
print('current '+a)
list2.append(a)
l1 = ['alice','bob','dog']
l2 = []
print(l1)
ZhuanYi(list1=l1[:],list2=l2)
print("--------------------")
#l1副本传入函数后 l1本身不会改变
print(l1)
5.传递任意数量的实参
为函数设置一个形参 ,前面加一个'*',此时不管调用语句提供了多少个实参,这个形参都能将它收入囊中:
def make_pizza(*toppings):
print(toppings)
print('make pizza with the following thing:')
for toping in toppings:
print('- '+toping)
make_pizza('mush','a','b')
print("---------------")
make_pizza('a')
- 结合使用位置实参和任意数量实参
def make_pizza(size,*toppings):
print(toppings)
print('make a '+str(size)+' inch pizza with the following thing:')
for toping in toppings:
print('- '+toping)
make_pizza(12,'mush','a','b')
print("---------------")
make_pizza(16,'a')
- 使用任意数量的关键字实参
使用任意数量的关键字实参,函数在调用时可以接受任意数量的键值对。在形参前加符号'**'
def build_profile(first_name,last_name,**user_info):
person = {}
person['f_name'] = first_name
person['l_name'] = last_name
for key,value in user_info.items():
person[key] = value
return person
print(build_profile('james','le',location='taian',age=27,filed='math'))
6.将函数存储到模块中
可以把写好的函数放在一个.py文件(模块)中,可以在同目录下的其他.py文件中导入。
当然也可以不在同一目录下,此时前面加上相对/绝对路径即可。
引用Python内建的模块,操作也是一样的。
现有apple.py,其中的内容如下:
def add(a,b):
return a+b
def mul(a,b):
return a*b
def minus(a,b):
return a-b
现在在同一路径下的其他.py文件中对他进行引用:
- 导入整个模块
import apple
print(apple.add(1,2)) #使用apple.的形式调用 模块内的函数
print(apple.minus(3,4))
- 导入特定的函数
形式:
from module_name import function_name
from module_name import function_name1.function_name2 #可以有多个 ,隔开
from apple import add,minus
print(add(1,2)) #可以直接使用函数名调用
print(minus(3,4))
- 使用as 给函数更名
from module_name import function_name as fn
from apple import add as A
from apple import mul as M
print(A(1,2)) #可以直接使用更名调用
print(M(2,2))
- 使用as给模块更名
import module_name as mn
import apple as a
print(a.add(1,2)) #使用a.的形式调用 模块内的函数
print(a.minus(3,4))
- 导入模块中的所有函数
from module_name import *
from apple import *
print(add(1,2)) #可以直接使用函数名调用
print(mul(2,2))
print(minus(1,4))