热门IT资讯网

Python之函数详解

发表于:2024-11-21 作者:热门IT资讯网编辑
编辑最后更新 2024年11月21日,Python之函数详解一、函数的概述简单地说,函数就是个黑匣子,它接收输入(参数),然后执行特定任务以完成特定功能,最后生成输出(返回值)。其中,输入(参数)和输出(返回值)都是可选的,也就是说,可以

Python之函数详解

一、函数的概述

简单地说,函数就是个黑匣子,它接收输入(参数),然后执行特定任务以完成特定功能,最后生成输出(返回值)。其中,输入(参数)和输出(返回值)都是可选的,也就是说,可以有也可以没有函数就是执行特定任务以完成特定功能的一段代码。可以在程序中将某段代码定义成函数,并指定函数名及接收的输入(参数),这样,就可以在程序的其它地方通过函数名多次调用并执行该段代码了每次调用并执行后,都会根据接收的输入(参数)执行特定任务以完成特定功能从而生成相应的输出(返回值)Python语言已经定义了很多内置函数。我们可以在程序中通过函数名直接调用这些内置函数。例如:当我们调用内置函数id()时,输入(参数)是任意的对象,完成的特定功能是获取输入(参数)的唯一标识,输出(返回值)是输入(参数)的唯一标识。


二、为什么需要函数

1.复用代码 如果在程序中需要多次完成某个特定的功能,我们无需把这个特定功能的相关代码在多个地方编写多次,完全可以把这个特定功能的相关代码定义成函数,然后在多个地方调用该函数,每次调用都会把函数对应的相关代码执行一遍。

2.隐藏实现细节 函数就是个黑匣子,将实现细节隐藏起来了。很多时候我们无需关注函数的实现细节,只需关注其接收的输入(参数)及生成的输出(返回值)就可以了。

3.提高可维护性 把完成某段特定功能的代码定义为函数后,如果需要对这段代码进行修改,只需要在一个地方进行修改,提高了程序的可维护性。否则,你需要找到这段代码的多个不同地方,每个地方都要进行同样的修改,费事费力还容易出错。

4.提高可读性、便于调试每个函数都对应一段完成特定功能的代码,提高了程序的可读性,也便于程序调试。


三、函数的定义和调用

1、定义函数定义

函数的语法格式

def 函数名([形式参数1,形式参数2,形式参数n]):

函数体

其中,def是 Python定义的关键字。


关于函数名的说明

a) 每个函数都有一个函数名,用于函数的调用。

b) 函数名属于标识符,因此,必须遵守标识符的命名规则,推荐遵守标识符的命名规范。


关于形式参数的说明

a) 形式参数简称形参

b) 形参用于在调用函数时接收输入,也就是接收传递的实际参数(简称实参)

c) 形参用中括号括起来,表示形参时可选的,也就是说,可以定义也可以不定义。

d) 形参的本质是变量,其作用域(起作用的范围)仅限于函数体


关于函数体的说明

a) 函数体是用于执行特定任务以完成特定功能的主体代码

b) 函数体对应的代码块必须缩进。

c) 如果函数需要有输出(返回值),可以在函数体内通过语句 return xxx进行返回,同时结束函数体的执行。

如果函数不需要有输出(返回值),可以在函数体内通过语句 return直接结束函数体的执行,或者让函数体正常执行结束,其实,函数在这两种情况下都是有返回值的,其返回值都是None。

d) 函数体在调用函数时才会被执行,因此,定义函数不会改变程序的执行流程。


2、函数调用

调用函数时,每个实参都被用于初始化相应的形参。所有形参都被初始化之后,函数体对应的代码块被执行。程序的执行流会跳转到定义函数的函数体内,执行函数体对应的代码块,执行完函数体后再跳回到调用函数的地方,继续执行下一条语句。


def test(arg1,arg2):    if arg1 and arg2:        return arg1 and arg2    elif arg1 or arg2:        return arg1 or arg2    else:        return False        print(test('hi',1)) # 1print(test(1,[])) # 1print(test('',[])) # False


四、函数调用之位置实参

调用函数时,可以根据每个形参在所有形参中的位置传递对应位置的实参,从而用每个实参初始化对应位置的形参,这样的实参称为位置实参。

def test1(arg1,arg2,arg3):    print('a = ', arg1, 'b = ', arg2, 'c =', arg3)# 实参位置不同是,初始化的形参值也不同,返回的值也会有变化test1(1,2,3) # a =  1 b =  2 c = 3test1(3,2,1) # a =  3 b =  2 c = 1


五、函数调用之关键字实参

调用函数时,传递的实参的形式可以为: 形参名=实参值,从而用指定的实参值初始化指定名称的形参这样的实参称为关键字实参。

def test2(a,b,c):    print('a = ', a, 'b = ', b, 'c = ', c)# 调用函数时,可以指定实参值初始化指定名称的形参test2(a = 1, b = 2, c = 3) # a =  1 b =  2 c =  3test2(a = 3, b = 1, c = 2) # a =  3 b =  1 c =  2


六、函数调用之实参传递

对于传递不可变类型的实参和可变类型的实参,传入可变类型的实参值会受到函数体内运算的影响。不可变类型的实参则不受影响。

def test3(arg1,arg2):    arg1 * 10    arg2.append(4)    print(arg1,arg2)i = 10L = [1,2,3]test3(i,L) # 10 [1, 2, 3, 4]print('i的值', i, 'L的值', L) # i的值 10 L的值 [1, 2, 3, 4]


七、函数的定义之多个返回值

如果需要在调用函数后有多个返回值,可以在定义函数时在函数体内使用 return语句返回由多个返回值组成的元组。

def test4(arg1):    even = []    odd = []    for i in arg1:        if i % 2:            even.append(i)        else:           odd.append(i)    # return 定义返回两个列表的值    return even,oddL = list(range(1,11))print(test4(L)) # ([1, 3, 5, 7, 9], [2, 4, 6, 8, 10])


八、函数定定义之带默认值的形参

定义函数时,可以给形参设置默认值,这样,调用函数时如果不传递对应的实参,就会使用设置的默认值初始化形参。给形参设置默认值的语法格式为: 形参=默认值 给形参设置默认值之后,可以简化函数的调用,只有与默认值不符的形参才需要传递额外的实参。

def test5(a,b = 5):    print('a = ', a, 'b = ', b)    test5(10) # a =  10 b =  5 未传入b的实参,使用默认值b = 5


九、函数定义之使用*定义关键字形参

定义函数时,可以在所有形参的某个位置添加一个*,这样,*后面的所有形参都被定义为只能接收关键字实参的关键字形参。

def test6(a,b,*,c,d):    print('a = ', a, 'b = ', b, 'c = ', c, 'd = ', d)# 调用函数时,必须传入c = xx d = xx的关键字参数test6(1,2,c = 3,d = 4) # a =  1 b =  2 c =  3 d =  4#test6(1,2,3,4)  test6() takes 2 positional arguments but 4 were given


十、函数定义之使用*定义个数可变的位置形参

定义函数时,可能无法事先确定传递的位置实参的个数,在这种情況下,可以在形参前添加一个*,将形参定义为个数可变的位置形参,从而可以接收0个或任意多个位置实参。这些位置实参会将个数可变的位置形参初始化为一个元组。

def test7(arg1,*arg2):    print('arg1 = ', arg1, '*arg2 = ', arg2)    # 传入实参时可以传入多个参数,arg1接收第一个参数,*arg2接收剩余的参数test7(1,2,3,4) # arg1 =  1 *arg2 =  (2, 3, 4)


十一、函数调用之使用*将序列中的每个元素转换为位置实参

调用函数时,可以在序列前面添加一个*,从而将序列中的每个元素都转换为一个单独的位置实参。

def test8(a,b,c):    print('a = ', a, 'b = ', b, 'c = ', c)    L = [1,2,3]# 正常调用,需要依次传递L的索引作为实参,然后初始化形参test8(L[0],L[1],L[2]) # a =  1 b =  2 c =  3# 调用时使用*,将序列中的每一个元素转换成单独的位置实参test8(*L) # a =  1 b =  2 c =  3


十二、函数定义之使用**定义个数可变的关键字形参

定义函数时,可能无法事先确定传递的关键字实参的个数,在这种情况下,可以在形参前添加两个*将形参定义为个数可变的关键字形参,从而可以接收0个或任意多个关键字实参。这些关键字实参会将个数可变的关键字形参初始化为一个字典。

def test9(**kwargs):    print(kwargs)    #传入多个关键字实参,初始华**kwargs,以字典的形式返回值test9(a = 1, b = 2, c = 3) # {'a': 1, 'b': 2, 'c': 3}# 因为位置形参必须要在关键字形参之前,所以个数可变的位置参数必须在个数可变的关键字参数之前def test10(*args,**kwargs):    print(args,kwargs)test10(1,2,3,a = 11, b = 12) # (1, 2, 3) {'a': 11, 'b': 12}


十三、函数调用值使用**将字典的每个键值对都转换为关键字参数

调用函数时,可以在字典前添加两个**,从而将字典中的每个键值对都转換为一个单独的关键字实参。

def test11(a,b,c):    print('a = ',a, 'b = ', b, 'c = ', c)    d = {'a':1,'b':2,'c':3}test11(**d) # a =  1 b =  2 c =  3
0