本章内容
- 函数
- 参数介绍
- 全局变量和局部变量
- 嵌套函数
- 匿名函数
前言
函数,说白了就是一是一个公式。我们读书的时候学习的一元函数、二元函数这之类的都是函数,在数学中函数的作用是为了是我们解题更轻松、更简单。而我们编程中的函数则是封装功能,以便于后续的使用。
一、函数
函数是 Python 为了代码最大程度的重用和最小化代码冗余而提供的最基本的程序结构。
函数就是对功能的封装,比如我们写了一个用户验证程序,而现在我又需要写一个用户管理系统,管理系统中有很多的操作,要求用户每进行一步操作就要进行一次用户验证(哈哈,实际情况肯定不会这样,这里用来举例),我们是不是要把用户验证程序的代码复制粘帖到每一步操作的开头?答案是的!卧槽,这也太坑爹了,那如果我有一万个操作呢?你还就别说我就复制粘帖一万次,复制粘帖
Python提供了许多内建函数,比如print () ,当然我们也可以自己定义一个函数,即用户自定义函数。
函数语法:
def 函数名(参数):
功能1
功能2
······
return 返回值(可以无返回值)
简单实例
1 def main(name): 2 #定义函数名为main,形参为name 3 4 if name == "Lyon": 5 #如果实参name等于 "Lyon" 6 7 print("Welcome Lyon !") 8 #打印内容 9 10 else: 11 #否则 12 13 print("泥奏凯!") 14 #打印泥奏凯 15 16 main('Lyon') 17 #通过 ( ) 来进行调用,并将位置参数 " Lyon" 传进去 18 19 main('SB') 20 #调用main( )
注:函数如果不进行调用是不会执行的,调用方式是以函数名加括号即:main( ),来进行调用的,不过以上例子需要传参数,不传就会报错。
二、参数介绍
形参:变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只在函数内部有效。函数调用结束返回主调用函数后则不能再使用该形参变量。
实参:可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使参数获得确定值。
位置参数:即参数必须以正确的顺序传入函数,传入的数量必须和声明的一样,不一样就报错。(还有地方叫必备参数之类的,一样的东西)
1 def main(name,age): 2 #在上例中增加一个位置参数 age 3 4 if name == "Lyon" and age == 18: 5 print("Welcome Lyon !") 6 else: 7 print("泥奏凯!") 8 9 main("Lyon",18) # print: Welcome Lyon 10 main(18,"Lyon") # print: 泥奏凯
默认参数:调用时不指定就以默认值传入,指定则按指定值传入。
1 def main(age,name="Lyon"): 2 #给形参name设置默认参数为 "Lyon"
注:通过默认参数,我们就算不传参数也不会报错。即name默认为 "Lyon" 。
关键参数:正常情况下,给函数传参数的时候要按照顺序传,如果不想按照顺序就可以使用关键参数。
1 def main(age,sex,name="Lyon"): 2 #加一个关键参数sex 3 4 if name == "Lyon" and age == 18: 5 print("Welcome Lyon !",sex) 6 else: 7 print("泥奏凯!") 8 9 main(18,name='Lyon',sex='male') 10 #关键参数不用按照顺序传入,当然关键参数必须写在位置参数后面
非固定参数:当我们想要传入多个参数,但是我们又不确定的时候就可以使用非固定参数。固定参数有两个,一个 *args(传入参数会变成一个元组) 以及 **kwargs(传入参数会变成一个字典)。
1 def main(*args,**kwargs): 2 #设置两个非固定参数 3 4 print(args,type(args)) 5 #打印args,以及args的类型 6 7 print(kwargs,type(kwargs)) 8 #打印kwargs,以及kwargs的类型 9 10 main((1,2,34),{1:2,3:4}) 11 #为非固定参数传参
注:*args为一个元组,**kwargs为一个字典
非固定参数还可以用*号来进行传递,即 *(1,2,34)
参数顺序及组合问题
首先说一下参数顺序问题:
在函数头部(定义参数):一般参数 --> 默认参数 --> 非固定参数*args --> 非固定参数**kwargs
在函数调用中(传递参数):位置参数 --> 关键字参数 --> 默认参数 --> 非固定参数*args --> 非固定参数**kwargs
参数组合使用问题:
在我们使用过程中,如果没有非固定参数,那么我们的关键参数或者默认参数可以用关键字进行传递。如果有非固定参数,必须按照位置参数的方式进行传递。
默认参数和非固定参数*args位置可以进行调换,调换后默认参数传递需要加上关键字。
三、全局变量和局部变量
局部变量:只在函数内部起作用的变量
全局变量:在整个程序中都起作用
1 name = "Lyon" 2 #name------> 全局变量 3 4 def func(name): 5 #定义一个函数func,形参为name 6 7 print(name) 8 #打印name 9 10 name = "yangyonog" #name------> 局部变量 11 #修改name 12 13 print(name) 14 #打印name 15 16 func(name) 17 #调用函数,并将全局变量name传入 18 19 print(name) 20 #打印最后结果 21 22 ''' 23 结果:Lyon 传入的全局变量name 24 yangyonog 打印的局部变量name 25 Lyon 全局变量并没有发生变化 26 '''
总结:全局变量作用域是整个程序,局部变量作用域是定义该变量的子程序。当全局变量与局部变量同名时:在定义局部变量的子程序内,局部变量起作用;在其他地方全局变量起作用。
返回值:我们函数执行后可以利用return语句把结果返回。不使用return即返回None,没有返回值。函数在执行过程中如果遇到return语句,就会停止并返回结果。
global语句:可以将局部变量变成全局变量,在函数内部变量前加上 global 即可 比如:global name
四、嵌套函数
嵌套函数即函数里面再套一个函数:
1 name = "Lyon_1" 2 #全局变量name 3 4 def func(): 5 name = "Lyon_2" 6 #第一层局部变量 7 8 print("第1层打印",name) 9 def func2(): 10 name = "Lyon_3" 11 #第二层局部变量 12 13 print("第2层打印", name) 14 def func3(): 15 name = "Lyon_4" 16 #第三层局部变量 17 18 print("第3层打印", name) 19 20 func3() # 调用内层函数 21 func2() # 调用内层函数 22 func() 23 24 print("最外层打印", name)
注:嵌套函数不能越级调用,级不能在func中直接调用func3。
nonlocal语句:主要是用在嵌套函数中,改变变量的作用域,但是不会扩展到全局变量。即只能在函数内部改变。nonlocal声明之后,会从上层开始找并返回第一个变量。没找到则报错。
1 def func(arg): 2 n = arg 3 def func1(): 4 n = 2 5 def func2(): 6 nonlocal n # n = 2 7 n += 1 8 func2() 9 print(n) # n = 3 10 func1() 11 print(n) 12 func(10)
五、匿名函数
匿名函数是一个表达式,并且不需要指定函数名,也就是它是一个没有名字的函数。匿名函数主要用于写一些简单的方法,对于复杂的还是用函数来写吧。
并且匿名函数主要是用于和其他函数搭配用。
1 #打印一个数的平方,普通函数版本 2 def func(x): 3 x *= x 4 print(x) 5 func(5) 6 7 #匿名函数版本 8 func = lambda x:x * x 9 print(func(5))
与其他函数搭配使用:
1 res = map(lambda x:x*x,[1,2,3,4,5]) 2 #map函数有两个参数,第一个参数为一个func(函数),第二个参数为iterable(可迭代对象) 3 #作用为将第二个参数中的所有元素作为参数,传入func中并返回结果 4 print(type(res)) 5 for i in res: 6 print(i)
为了减少篇幅,高阶函数将放到下一章《装饰器》中一起整理。
来源:https://www.cnblogs.com/yangweirdo/p/7228056.html