函数补充
函数
什么是函数:
函数就是一段有特定功能代码的封装
函数名的明明规范(符合python中变量的命名规范) # 多个单词需要下划线分隔开
函数的参数和返回值
函数可以接受外界传递的实参值,在函数体内就可以通过使用形参的值
函数可以有返回值,返回结果给函数的调用者
函数定义的格式
def 函数名(形参名1,形参名2...):
函数体
[return [返回值]]
# []表示可有可没有
函数名是符合python中命名规范的标识符即可,采用小写字符,如果是多个单词的话,中间使用_分隔,和变量的命名规范一致。
形参列表:函数名后面()中定义的变量就是形参,多个形参组成形参列表。
如果没有参数的话,()不可以省略。
和函数名一样,形参名也是符合python中的命名规范的标识符即可。
形参的作用域是整个函数体内,出了函数体,形参就不可用了。
函数体:由一条或者多条语句组成。
例如:循环结构,分支结构,变量定义,打印语句等都是可以出现的函数体中的。
如果函数什么语句都不执行的话,必须使用pass占位。否则是语法错误。
return关键字,表示函数调用后,要返回给调用者的返回值。
默认函数都返回的是None值。
如果想返回非None的值,必须是使用return + 要返回的值。
需要注意的是:函数的返回值可以是python中的任意类型,甚至个数也可以是多个
函数定义的关键:
定义函数时,需要注意两个关键点,定义函数就不成问题:
1.函数的形参定义:
函数的形参是函数需要的关键数据,函数是否需要参数,需要多少个参数,都是根据具体的业务逻辑决定的,没有固定的格式。
2.函数的返回值:
函数的返回值也是根据具体的业务逻辑决定的。
定义空参,无返回值的函数
def say_hello():
print('helloword')
定义空参,有返回值的函数
def get_int():
return 10
定义有参,无返回值的函数
def show(name):
print("hello{}!".format(name))
定义有参,有返回值的函数
def add(a,b):
return a + b
函数的调用
python中函数都是有返回值的,即使没有显式的使用return语句返回,也是有默认的返回值:None.
所以,根据对返回值的使用,分成以下几种情况:
1.把函数的返回值赋值给变量
def add(a,b):
return a + b
# 把add函数的返回值赋值给变量res
res = add(1,2)
2.把函数的返回值当成参数传递给其他函数
def add(a,b):
return a + b
def show(x):
print(x)
# 把add函数的返回值当成参数传递给show函数
show(add(1,2))
# 把add函数的返回值当成参数传递给内置的print函数
print(add(1,2))
3.把函数的返回值当成表达式的一部分
def add(a,b):
return a + b
# 使用add函数的返回值构建表达式
res = add(1,2) + add(100,200)
print(res)
注意:在使用函数的返回值的时候,一定要注意函数的返回值的数据类型。
不同的数据类型在一起使用的时候,往往会造成异常。
def add(a,b):
return a + b
# res = "abc" + add(1,2) # 字符串和int型不能直接相加
4.不理会函数的返回值
如果函数没有显式的返回值,或者返回值是None话,如果需要对函数的返回值进行判断,可以用变量接收,如果不关心函数的返回值的话,可以不用理会函数的返回值。
def func():
print(123)
# 直接调用函数,但是并不关心函数的返回值
func()
关于函数的形参列表
函数的形参可以在函数体中直接使用,因为函数一旦调用,形参必定会被赋予一定的值。(实际上函数的调用过程就是实参给形参赋值的过程。)
根据给形参赋值的方式,分为以下几种:
1.按位置传参
在函数调用时,直接在函数名后的()中加的实参值,会按照在函数定义时的顺序依次给形参赋值。
def func(a,b,c):
pass
func(1,2,3) # 1赋值给a,2赋值给b,3赋值给c
func(10,20,30) # 10赋值给a,20赋值给b,30赋值给c
2.关键字传参
在函数调用时,通过指定接收的形参名达到给形参赋值的目的。
def show(name,age,addr):
print('姓名:{},年龄:{},地址:{}'.format(name,age,addr))
# 通过关键字传参的方式,可以不必理会函数定义时参数的顺序
show(age=10,name='abc',addr='BeiJing')
关于默认值参数
调用函数时,需要给函数传递足够数量的参数,否则函数的形参就得不到赋值,此时会报错
def func(a,b,c):
pass
# func(1,2) # 函数需要三个参数,实际传递了两个,所以报错
在调用者没有给某些形参传值的时候,参数可以有默认值,这样就防止了函数调用出错。
def func(a,b,c=0):
pass
func(1,2) # ok
有默认值参数的函数,既可以给默认值参数传值,也可以不传值,不传值时,使用的就是函数定义时的默认值,传值的话,使用的就是调用者传递的值。
3.接收不确定个数的参数
假设有如下使用场景:
定义一个函数,有两个参数,打印所有的参数信息:
def f1(a,b):
print(a,b)
若现在要定义一个函数,打印三个参数的信息:
def f1(a,b,c):
print(a,b,c)
如果需求继续增加,恐怕要针对不同个数的参数分别定义一个函数才能满足需求了,这明显不符合代码复用的原则。
为了满足这种可以接收个数不确定的参数的场景,python中可以定义可变参数的函数。
def f1(a,b,*args):
print(a,b,args)
# 函数调用
f1(1,2)
f1(1,2,3)
f1(1,2,3,4)
在形参列表中使用*+参数名表示一个形参,该形参可以用来接收个数不确定的实参赋值。在函数内部,实际上多个参数是被组织成一个元组的形式.args就是元组名。
可以在函数中查看args这个形参的类型,结果就是元组类型。
def f1(a,b,*args):
print(type(args)) # tuple
print(a,b,args)
除了可以接收个数不确定的顺序参数外,函数中还可以使用**+参数名的方式来定义能接收个数不确定的关键字参数。
def f2(a,**kwargs):
print(type(kwargs)) # dict
print(a,kwargs)
f2(1,age=10,name='abc')
f2(1,addr='beijing',age=10,name='abc')
在函数内部,多个关键字参数会被组织成字典.kwargs就是字典名。
拥有各种类型形参定义的函数
如果把顺序参数,默认值参数,不确定个数的顺序参数,不确定个数的关键字参数都定义在一个函数中的话,各种参数之间应该遵守一定的顺序:
def f3(a,*args,age=10,**kwargs):
print(a)
print(args)
print(age)
print(kwargs)
注意:
个数不确定的参数不一定非得接收参数,如果没有给不确定个数的参数传值的话,他们将是空元祖或者是空字典。
关于函数的返回值:
1.如果函数的参数是一个可变数据类型的话,比如列表和字典,那么在函数体中对形参列表的修改,可以直接反应在列表本身,在函数外也是可以看到改变的,此时函数就不需要再把列表当成函数的返回值了。
def f(lst):
lst.append(888)
return lst
lst = [1,2,3]
lst = f(lst)
print(lst)
由于列表是可变的,所以,在函数中无需将改变的列表返回
def f(lst):
lst.append(888)
lst = [1,2,3]
f(lst)
print(lst)
2.如果是不可变的数据类型在函数中发生了改变,函数外是看不到的,所以,如果想看到函数中数据的变化结果,就必须使用return将改变后的结果返回了。
def new_str(name):
return '---{}---'.format(name)
s = 'andy'
ss = new_str(s)
print(ss)