一、函数的简介
函数在Python中是最基本的程序结构,用来最大化地让我们的代码进行复用。简单地说,一个函数就是一组Python语句的组合,它们可以在程序中运行一次或多次运行。Python中的函数在其他语言中也叫做过程或子例程,那么这些被包装起来的语句通过一个函数名称来调用。有了函数,可以在很大程度上减少复制及粘贴代码的次数了。可以把相同的代码可以提炼出来做成一个函数,在需要的地方只需要调用即可。那么这样就提高了代码的复用率了,整体代码看起来比较简练,没有那么臃肿了。
- 封装具备特定功能的一段代码,以便在其他地方调用
- 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段
- 函数能提高应用的模块性,和代码的重复利用率
- 你已经知道Python提供了许多内建函数,比如print(),但你也可以自己创建函数,这被叫做用户自定义函数
二、函数的定义
1、函数定义的格式
- 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号()
- 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数
- 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明(前文已经讲过)
- 函数内容以冒号起始,并且缩进,相同缩进为同一函数体
- return [表达式] 结束函数,选择性地返回一个值给调用方
- 不带表达式的return或者没有return相当于返回 None
def functionname( parameters ):
"函数_文档字符串"
function_suite
return [expression]
函数的调用
1、输出调用
- 用于函数只调用一次,后续不会再次使用到
- 尽量用于带返回值的方法
def addTwo(a,b):
return a+b
print(addTwo(12,21))
2、赋值调用
- 函数的返回结果可能需要在后续代码中使用到
- 用于函数中使用return返回值的情况
def addTwo(a,b):
return a+b
result = addTwo(12,21)
print(result+1) #可以直接在赋值变量直接加减
3、直接调用
#一个99乘法表的功能实现
def ninenine():
for i in range(1,10):#表示行
for j in range(1,10):#表示列
if j<=i:#列的编号总是小于等于行数
print("%d*%d=%2d"%(j,i,i*j),end="\t")
else:
break
print()
#输出调用(None)
print(ninenine())
#赋值调用
# aaaaa=ninenine()
# print(aaaaa)
#直接调用
ninenine()
四、函数中的参数传递
1、 不可变类型
不可变类型有整数、字符串、元组,在函数调用时传入不可变类型变量作为实际参数,并对该参数值进行了修改,该修改不影响变量值本身。
def changeInt(a):
a = 10
print(a)
b=2
changeInt(b)
print(b)#结果b=2,a=10不变化
2、可变类型
可变类型有列表、字典,在函数调用时传入可变类型变量作为实际参数,并对该参数值进行了修改,该修改影响变量值本身。
def changeList(ll):
ll.append("aa")
print(ll)
list1 = ["allen","petter","lucy"]
changeList(list1)
print(list1)#列表list1和11都改变增加了"aa"元素
五、函数的参数
1、形参和实参
- 形参:在函数的定义阶段,括号内写的变量名,叫做该函数的形式参数,简称形参
- 实参:在函数的调用阶段,括号内实际传入的值,叫做实际参数,简称实参
- 形参就相当于变量名,而实参就相当于变量的值
- 函数调用传参的过程 就是给形参变量名赋值的过程
注意:形参和实参的绑定关系只在函数的调用阶段有效,函数运行结束关系自动解除,只在函数内部有效 函数外部无任何影响
def func(x,y):
"""
该函数的作用:
:param x: 对形参x的解释
:param y: 对形参y的解释
:return: 返回值
"""
return x+y
#此处的12、23分别是实际参数,用于填充形参x、y的位置
func(12,23)
2、位置参数
在函数定义阶段按照位置从左往右依次书写的变量名,叫做函数位置形参。
- 传入参数个数必须与声明一致,否则Python解释器会报错
- 传入参数的顺序必须与声明一致
- 传入参数的类型如果不一致,解释器无法帮我们检查,需要在代码中添加判断语句(错了,但是显示的None)
def addT(a,b):
return a
#addT() missing 1 required positional argument: 'b'
# addT(12)
# addT() takes 2 positional arguments but 3 were given
# addT(12,3,2)
# addT(12,3)
3、关键字参数
按照key=value的形式定义的实参,无需按照位置为形参传值。
- 关键字实参必须在位置实参右面
- 对同一个形参不能重复传值
- 使用关键字传参数,可以避免参数位置顺序不一致问题
def print_hello(name, sex):
# if not isinstance(sex,int):#判断sex是否是一个int的实例(对象)
# raise TypeError("请输入整形数据sex!!!")
sex_dict = {1:u'先生', 2:u'女士'}
print('hello %s %s, welcome to python world!' %(name, sex_dict.get(sex)))
# 1、正确用法,输出:hello allen 先生, welcome to python world!
# print_hello(sex=1,name='allen')
# 2、错误用法,输出:print_hello() missing 1 required positional argument: 'sex'
# print_hello(name='allen')
# 3、错误用法,输出:print_hello() missing 1 required positional argument: 'name'
# print_hello(sex=1)
# 4、正确用法,先位置参数再关键字参数,输出:hello allen 先生, welcome to python world!
# print_hello("allen",sex=1) #这个是可以的
# 5、错误用法,先关键字参数后位置参数,输出:positional argument follows keyword argument
# print_hello(name = "allen",1)
# 6、错误用法,重复给一个关键字赋值,输出:SyntaxError: keyword argument repeated
# print_hello(name = "allen",name="aa")
4、默认值参数
形参在定义时就已经为其赋值,可以传值也可以不传值,经常需要变得参数定义成位置形参,变化较小的参数定义成默认参数(形参)。
- 只在定义时赋值一次
- 默认参数的定义应该在位置形参右面
- 默认参数通常应该定义成不可变类型
# print方法中的end可以不指定,默认使用\n,也可以指定为其他结束字符
# print("asdfasd",end='\n')
# 定义一个方法,把一个人的信息录入列表
list1 = []
def addInfo(name,age,school='成都'):
list1.append(name)
list1.append(age)
list1.append(school)
addInfo("小王",23)
addInfo("小赵",24,"北京")
print(list1)
5、不定长参数
可变长指的是实参值的个数不固定,而实参有按位置和按关键字两种形式定义,针对这两种形式的可变长,形参对应有两种解决方案来完整地存放它们,分别是*args、**kwargs。
- 指定星号(*)的变量名会存放所有未命名的参数,如果在函数调用时没有指定参数,它就是一个空元组,如果指定了,会将参数放入元组。
def add(a,b,*args):
# print(type(args))
# print(args)
sum = a+b
for i in args:
sum +=i
return sum
# <class 'tuple'>
print(add(1,2,3,4,5,6))
- 指定**kwargs的变量名会存放未命名的参数,他需要在调用方法时候使用关键字参数进行传递,并将多余的数据存储在一个字典类型中。
def fun(x,y,**kwargs):
print(x,y,kwargs)
#全部关键字传参,没有问题
fun(x = 10,y = 20,z= 30,w = 50)
#前两个有位置参数可以,多余的需要关键字传参
fun(10,20,c=30,w = 50)