函数补充

函数

什么是函数:

函数就是一段有特定功能代码的封装

函数名的明明规范(符合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)
posted @ 2019-04-01 22:51  blog_wu  阅读(210)  评论(0编辑  收藏  举报