函数
函数就是一段封装好的,可以重复使用的代码;在封装时给它起一个独一无二的名字,只要知道它的名字就能使用这段代码,还可以接收数据,并根据数据的不同做出不同的操作,最后再把处理结果反馈给我们。
概念点:代码重复利用,代码进行封装,可接收处理数据;
python常用内置函数在builtins.py中,可以直接使用
print() # 输出
type() # 返回类型
id() # 返回内存地址
input() # 输入
len() # 返回长度
open() # 打开文件
round() #返回浮点数x的四舍五入值
abs() # 取绝对值
函数调用
调用函数也就是执行函数。如果把创建的函数理解为一个具有某种用途的工具,那么调用函数就相当于使用该工具。
在Python中调用一个函数,需要知道这个函数的名称和传入参数
a1 = abs(-1)
print(a1) # 1
a2 = abs(-1,-2)
print(a2) # TypeError: abs() takes exactly one argument (2 given)
a3 = abs('a')
print(a3) # TypeError: bad operand type for abs(): 'str'
'''
函数名其实就是指向一个函数对象的引用,完全可以把函数名赋给一个变量,相当于给这个函数起了一个“别名”
'''
a4 = abs # 变量a4指向abs函数
print(a4) #
print(a4(-1)) # 1
调用函数的时候,如果传入的参数数量不对,会报TypeError
的错误,并且Python会明确地告诉你:abs()
有且仅有1个参数,但给出了两个;
如果传入的参数数量是对的,但参数类型不能被函数所接受,也会报TypeError
的错误,并且给出错误信息:str
是错误的参数类型;
自定义一个函数
除了可以直接使用的内置函数外,Python 还支持自定义函数,即将一段有规律的、可重复使用的代码定义成函数,从而达到一次编写、多次调用的目的。
Python中定义一个函数(创建一个函数),使用 def 关键字,def+函数名+(参数)+: ,通过语句块缩进来编写函数体,通过 return 来返回值
语法格式:
def 函数名(参数): # 函数名就是python的语法的标识符,函数名最好能够体现出该函数的功能
实现特定功能的多行代码
[return [返回值]] # return为非必须,是否需要return值要根据该函数具体实现的功能决定
def add(x,y):
sum = x + y
return sum
a = add(2,3)
print(a) # 5
def add(x,y):
sum = x + y
a = add(2,3)
print(a) # None
注:函数需要return来把数据返回给外部调用,如果不写return,函数默认return None,在创建函数时,如果该函数没有参数,也必须保留()
函数在内部执行语句时,一旦执行到return,函数就执行完毕并把结果返回,即使return下面有同样缩进的语句块,但并不会执行
def add(x,y):
sum = x + y
return sum
print("这是函数中return后的语句") # 在调用函数时,该print语句并不会被执行
空函数
有确定的 def+函数名+(参数)+: ,在函数体中用 pass 代替实际的代码语句
def func():
pass # pass语句什么都不做,实际上 pass 通常作为代码的占位符,在程序框架设计中常用
返回多个值
函数通过 return 返回单个值,同样也可返回多个值
def names(x,y):
name_1 = x
name_2 = y
return name_1, name_2
n = names('Jack','Flack')
print(n) # 返回('Jack', 'Flack')
print(type(n)) # 返回类型
Python中函数return多个值时,返回类型为 tuple(元祖),tuple中包含多个值
注:当一个函数有reutrn时,我们在调用这个函数时,需要自定义一个变量来接收函数return的值
任务:
定义一个函数,传入参数为一个整数列表, 如list_num = [1,2,3,4,5,6......n],对这个list 按 11+22+33+....+nn 累加,返回这个累加值。
函数的参数
函数参数的作用是传递数据给函数内部,令其对接收的数据做具体的操作处理;
位置参数,有时也称必备参数,指的是必须按照正确的顺序将实际参数传到函数中,换句话说,调用函数时传入实际参数的数量和位置都必须和定义函数时保持一致。
Python函数的定义比较灵活,除正常定义位置参数(必备参数)外,还可以使用默认参数、可变参数和关键字参数,在处理复杂参数的同时,方便简化调用
'''定义一个函数,实现x*x+1的计算'''
def formula(x):
return x*x+1
对于函数 formula(x) ,参数 x 就是一个必填参数也是形参,当我们调用 formula函数时,就必须传入并且只能传入一个参数 3或者其他实际数值也就是实参;
注意:形参与实参的数量必须保持一致
a1 = formula(3) # 调用formula函数,参数传入3,等同于x=3,把formula返回的对象赋值给变量a1
print(a1) # 10
a2 = formula(x=4)
print(a2) # 17
上面代码展示了对函数中参数两种赋值方式,一种通过位置隐式的把3赋值给参数x属于位置传参,另一种通过赋值符号 “=” 显式把4赋值给参数x属于关键字传参(关键字参数);
关键字参数:是指使用形式参数的名字来确定输入的参数值。通过此方式指定函数实参时,不再需要与形参的位置完全一致,只要将参数名写正确即可。
现在如果要通过函数来实现 x*x+ y,在formula的参数中就需要传入x, y两个参数
'''定义一个函数,实现x*x+y的计算'''
def formula(x,y):
return x*x+y
res_1 = formula(3,2) # 调用formula函数时,根据参数位置关系(位置传参)传入的参数为3和2,按照位置相当于x=3,y=2,结果为11
res_2 = formula(2,3) # 调用formula函数时,根据参数位置关系传入的参数为2和3,按照位置相当于x=2,y=3,结果为7
res_3 = formula(x=3,y=2) # 调用formula函数时,显式的给x,y参数赋值,x=3,y=2(关键字传参),结果为11
需要注意,混合传参时关键字参数必须位于所有的位置参数之后,否则Python 解释器会报如下错误
'''定义一个函数,实现x*x+y的计算'''
def formula(x,y):
return x*x+y
res_4 = formula(x=4, 5) #此处关键字传参在位置传参前,Python解释器会报错
SyntaxError: positional argument follows keyword argument
默认参数
根据 formula函数,如果实际工作中,这个函数更多的是用来计算 xx+1,但我们也需要这个函数能计算 xx+y,为了简化代码调用,可以给 y 指定一个默认参数 y=1
def formula(x,y=1):
return x*x+y
a5 = formula(3) # 调用formula函数时,虽然只传入的参数x=3,但定义函数时默认y=1,等价于 formula(3,1)所以结果为10
从上面例子可以看到,默认参数可以简化函数的调用,当参数y在定义函数时指定了默认值后,在后续其他代码调用该函数时,y参数可不传入参数(非必填参数),当y不传入参数时,y取默认值,当y被传入参数时,y取最新的值
需要注意:定义函数时,必选参数放前,默认参数放后
def formula(x=3,y): # SyntaxError: non-default argument follows default argument
return x*x+y
上面代码把x=3定义为默认参数,y为必选参数,解释器会报错:SyntaxError: non-default argument follows default argument
可变参数
例:当我们需要定义一个函数,实现aa+bb+cc+dd.......+n*n,n为任意数
def formula(*numbers): # *numbers为可变参数(numbers类型为元祖,用于接收任意个传入的参数),即调用该formula函数时,可传入任意数量参数
sum = 0
print(type(numbers),numbers) # numbers类型为元祖
for i in numbers:
sum += i*i
return sum
a6 = formula(1) # 此时可变参数numbers接收的参数是1,numbers = (1,),结果为1
a7 = formula(1,2,3) # 此时可变参数numbers接收的参数是1,2,3,numbers=(1,2,3),结果为14
如果需要传入的参数是一个list或tuple,可通过*+参数来对list或tuple解包
n = [1,2,3,4]
a8 = formula(*n) # *n作用是把n中的元素全部取出,放入numbers元祖中,等价于formula(1,2,3,4)
通过 *n 把 n这个list中所有元素解包后作为可变参数传入函数,是一种常用方法
可变关键字参数
可变关键字参数允许传入0个或任意个带参数名的参数,这些关键字参数在函数内部以字典的形式存储
'''定义一个函数,存储学生信息'''
def student_info(name, age, **kw):
student_name = name
student_age = age
other_inf = kw # **kw是以字典类型来存储传入的关键字参数
print("other_inf类型:",type(other_inf))
print(student_name, student_age, other_inf)
a9 = student_info('Jie',18)
# key_values类型:
# Jie 18 {}
a10 = student_info('Jie',18,city='Shanghai',country='China')
# other_inf类型:
# Jie 18 {'city': 'Shanghai', 'country': 'China'}
把一个已定义的字典作为关键字参数传入 student_info函数,可通过 **+变量名 实现
more_info = {'city': 'Shanghai', 'country': 'China'}
a11 = student_info('Jie',18,**more_info)
# **more_info作用是把字典more_info中的key:value解包后作为关键字参数以字典形式存入kw中
注意:**more_info 只是对more_info拷贝,因此在函数内更改这个more_info是不会对原来的more_info产生影响的
参数组合
在Python中定义函数时,可以用必选参数、默认参数、可变参数、关键字参数,组合使用
参数定义的顺序,必选参数-可变参数-默认参数-关键字参数
def func_1(a,b,*args,c=3,**kw):
print(f"参数a={a},参数b={b},可变参数args={args},参数c={c},关键字参数kw={kw}")
a12 = func_1(1,2) # 参数a=1,参数b=2,参数c=3,可变参数args=(),关键字参数kw={}
a13 = func_1(1,2,4,'A','B',k='D',v='E')
# 参数a=1,参数b=2,可变参数args=(4, 'A', 'B'),参数c=3,关键字参数kw={'k': 'D', 'v': 'E'}
小结:
1、Python函数定义中参数形态比较灵活,可以传入复杂的参数,方便简单调用;
2、必选参数必须在默认参数之前 ;
3、可变参数 *args,接收一个tuple;
4、可变关键字参数 **kw, 接收一个dict;
5、可变参数可直接传入,例:func(1,2,3),又可以通过list或tuple,再通过解包的方式传入:func((1,2,3));
6、关键字参数可直接传入:func(x=1,y=2),又可以通过dict,经过解包方式传入:func({'k'=1,'v'=1};
7、参数组合时,参数定义顺序:必选参数-可变参数-默认参数-可变关键字参数
练习小项目
需求:
老师需要一个自动点名器,用于从学生名单中随机选择一位同学来回答课堂提问,掌握学生知识掌握情况; 现在要求编写一个py模块,在模块中封装一个功能函数来实现该需求,所有学生姓名传入函数,老师运行该程序,就会在屏幕上随机返回一个学生的姓名