函数简介
函数的定义
函数的使用
ruturn 的使用
调用函数
函数传参
位置参数
关键字参数
默认参数
不定长参数
参数解包
函数简介
在程序中,具备某一功能的工具指的就是函数,事先准备工具的过程即函数的定义,拿来使用即函数的调用。
【print()】输出函数,【str()】等类型转换函数等等。这些其实都是Python的内置函数,
也就是Python语言本身就提供的。
函数的定义
函数的使用必须遵守‘先定义,后调用的原则。函数的定义就相当于事先将函数体代码保存起来,
然后将内存地址赋值给函数名,函数名就是对这段代码的引用,这和变量的定义是相似的。
没有事先定义函数而直接调用,就相当于在引用一个不存在的“变量”。
定义函数的语法
def 函数名(参数1,参数2,...):
''' 文档描述'''
函数体
return 值
- def:定义函数的关键字;
- 函数名:函数名指向函数内存地址,是对函数体代码的引用。函数的命名应该反映出函数的功能;
- () : 括号内的定义参数,参数是可有可无,且无需指定参数的类型;
- :括号后要加冒号,然后在下一行开始缩进编写函数体代码;
- ''' 文档描述''' :描述函数功能,参数介绍等信息的文档,非必要,但是建议加上,从而增强函数的可读性;
- 函数体:有语句和表达式组成;
- return 值:定义函数的返回值,return是可有可无的。
函数的使用
案列 :
def sports():
print('play basketball')
sports()
返回结果:
play basketball
若需要将函数体代码执行的结果返回给调用者,则需要用到return。return后无值或直接省略return,
则默认返回None,return的返回值无类型限制,且可以将多个返回值放到一个元组内。
def test(x,y,z):
return x,y,z #等同于return (x,y,z)
res=test(1,2,3)
print(res)
结果:
(1, 2, 3)
函数传参
def fun(形参):
代码块
调用函数:
fun(实参)
含义:声明函数时,在括号中定义需要传入的参数,调用函数时就必须传入参数
位置参数
案例:
声明函数,需要传入三个参数
def fun(name, age, gender):
print('名字:', name)
print('年龄:', age)
print('性别:', gender)
调用函数:
fun('tom', '20', 'male')
PS: 默认参数必须在位置参数之后;默认参数额值仅在函数定义阶段被赋值一次
x=1
def foo(a=x):
print(a)
x=5 #定义阶段a已被赋值为1,此处的修改与默认参数a无任何关系
foo()
结果:
1
默认参数的值通常应设为不可变类型
def foo(n, arg=[]):
arg.append(n)
print(arg)
return arg
foo(1)
foo(2)
foo(3)
结果:
[1]
[1, 2]
[1, 2, 3]
当一个参数不是必须传入时,就可以使用默认参数给定默认值但如果调用函数时指定了参数,则默认参数不生效
案列:
def fn(name, age, gender='male'):
print('名字:', name)
print('年龄:', age)
print('性别:', gender)
fn(name='tom', age=20, gender='female')#调用函数
结果:
名字: tom
年龄: 20
性别: female
不定长参数(与 *的用法)
参数的长度可变指的是在调用函数时,实参的个数可以不固定,而在调用函数时,实参的定义无非是按位置
或者按关键字两种形式,这就要求形参提供两种解决方案来分别处理两种形式的可变长度的参数
如果在最后一个形参名前加号,那么在调用函数时,溢出的位置实参,都会被接收,
以元组的形式保存下来赋值给该形参
案列:
def foo(x,y,z=1,*s): #在最后一个形参名args前加*号
print(x)
print(y)
print(z)
print(s)
foo(1,2,3,4,5,6,7) #实参1、2、3按位置为形参x、y、z赋值,多余的位置实参4、5、6、7都被*接收,以元组的形式保存下来,赋值给s,s=(4, 5, 6,7)
结果:
1
2
3
(4, 5, 6, 7)
不定长关键字参数
如果在最后一个形参名前加号,那么在调用函数时,溢出的关键字参数,都会被接收,
以字典的形式保存下来赋值给该形参
案列:
def foo(x, **s): # 在最后一个参数s前加**
print(x)
print(s)
foo(y=2, x=1, z=3) # 溢出的关键字实参y=2,z=3都被**接收,以字典的形式保存下来,赋值给s
结果:
1
{'y': 2, 'z': 3}
如果我们事先生成了一个字典,仍然是可以传值给**s的。
案列:
def foo(x, y, **s):
print(x)
print(y)
print(s)
dic = {'a': 1, 'b': 2}
foo(1, 2, **dic) # **dic就相当于关键字参数a=1,b=2,foo(1,2,**dic)等同foo(1,2,a=1,b=2)
结果:
1
2
{'a': 1, 'b': 2}
PS:如果在传入dic时没有加**,那dic就只是一个普通的位置参数了
参数解包
传递实参时,也可以在序列类型的参数前添加星号,这样它会⾃动的将序列 中元素依次作为参数传递
要求序列中的元素的个数必须和形参的个数⼀致
案列:
def lis(a, b, c):
print('a=', a)
print('b=', b)
print('c=', c)
n = ('tom', 'age', 'gender')
lis(n[0], n[1], n[2])
结果:
a= tom
b= age
c= gender
案列:
def lis(a, b, c):
print('a=', a)
print('b=', b)
print('c=', c)
dic = {'a': 1, 'b': 2, 'c': 3}
lis(**dic)
结果:
a= 1
b= 2
c= 3