什么是函数?
在我们之前学到的东西,都是一句一句的从上往下依次执行,并且如果有需要重复用到的代码,还要重新再写一下
那么,我们在程序开发的过程中,需要某块代码多次执行,但是为了提高编写效率,以及代码的重(chong)用,把具有独立功能的代码块,组织成一个小模块,这就是函数。
如何定义一个函数
def 函数名():
代码
代码示例:
def funname():
print('我是一个函数【方法】')
调用一个函数
定义了函数之后,就相当于有了一个具有某些功能的代码,想要让这些代码能够执行,需要调用它
调用函数通过 函数名() 即可完成调用
>>> def funname():
... print('我是一个函数【方法】')
...
>>> funname()
我是一个函数【方法】
>>>
- 定义函数名字遵循大小驼峰命名方法
练习1:
- 使用def定义函数,并调用
函数的文档说明
可以看到函数的相关说明
>>> def fun_test(a,b):
... "对两个正整数求积"
... print('两个数的乘积是:{}'.format(a*b))
...
>>> help(fun_test)
Help on function fun_test in module __main__:
fun_test(a, b)
对两个正整数求积
>>>
函数【方法】参数
有参数的函数
假设我们的函数内的参数是写死的
那么,这个函数就只能计算我们写的那两个数的乘积,这个函数也就失去了意义。
我们为了让一个函数更通用,可以计算任意两数的积,可以定义两个参数,让个两个参数代表任意的两个数字
什么是参数?
假设你本身叫李四,你有个QQ,昵称是王二麻子,还有个微信,昵称是魁拔
不管是叫你李四、王二麻子、魁拔都是叫的你这个人,你是不变的,这个称呼是变化的
那么,参数就可以理解为是一个代表性的字符,这个字符你可以让它代表1,也可以代表2,任意你想让他代表的数字
- 缺省参数
-
什么是缺省参数?
- 所谓缺省参数,顾名思义,就是在声明函数的某个参数的时候为之指定一个默认值,在调用该函数的时候如果采用该默认值,你就无须指定该参数。
- 注意:带有默认值的参数一定要位于参数列表的最后面。
def fun(a, b=1): print('a是{}'.format(a)) print('b是{}'.format(b)) # 示例1 fun(2, 3) # 结果如下: a是2 b是3 # 示例2 fun(2) # 结果如下: a是2 b是1
-
不定长参数
- 有时可能需要一个函数能处理比一开始声明时更多的参数。这些参数叫做不定长参数,声明时不会命名。
def funcname([formal_args],*args,**kwargs): "函数文档说明" 代码 返回值
*args:存放所有未命名的变量参数,args为元组
**kwargs:变量名会存放所有未命名的变量参数,**kwargs接收的是字典格式,即kwargs为一个字典
def func(item, *args, **kwargs): print("item是:{}".format(item)) print("args是:" + str(args)) print("args的类型是:" + str(type(args))) print("args的元素是:") for i in args: print(i) print("-"*40) print("kwargs是:" + str(kwargs)) print("kwargs的类型是:" + str(type(kwargs))) print("kwargs的元素是:") for k, v in kwargs.items(): print(k + ":" + str(v)) func(1, 'a', 'b', 'c', name='lisi', age=18) # 注意传递的参数对应
结果如下:
item是:1 args是:('a', 'b', 'c') args的类型是:<class 'tuple'> args的元素是: a b c ---------------------------------------- kwargs是:{'name': 'lisi', 'age': 18} kwargs的类型是:<class 'dict'> kwargs的元素是: name:lisi age:18
-
调用带有参数的函数
如上面的fun_test(a,b)函数,在调用这个函数的时候,我们会给它传入两个数字
>>> def fun_test(a,b):
... "对两个正整数求积"
... print('两个数的乘积是:{}'.format(a*b))
...
>>> fun_test(2,3) # 调用带有参数的函数时,需要在小括号中,传递数据
两个数的乘积是:6
>>>
- 定义时小括号中参数,用来接收参数用的,称为‘形参’
- 调用时小括号中的参数,用来传递给函数用的,称为‘实参’
推荐一个网站:http://www.pythontutor.com/
这个网站可以在线查看执行流程
练习
- 要求:定义一个函数,完成前2个数的加法操作之后,对最后一个数进行剑法操作
- 注意有三个参数
- 调用函数的时候,这个函数有几个参数,那么就需要传递几个参数
什么是函数返回值
假设你转微信给你的室友5块钱,帮忙给你带回来一瓶宅男快乐水~
>>> def fun_test(a,b):
... "对两个正整数求积"
... print('两个数的乘积是:{}'.format(a*b))
... return a*b
>>> fun_test(2,3)
两个数的乘积是:6
在上面代码中,你转微信5块钱给你的室友相当于调用函数
- 即fun_test()
5块钱,相当于传递参数【实参】
- 2,3
带回来宅男快乐水相当于返回值
- return a*b
但是,你给了5块钱,还剩2块,你又跟你室友说再帮带一包干脆面,剩下的一块当路费~~
那就是说,函数的返回值可以有多个
def fun():
a = 1
b = 2
return a,b
返回的结果是元组类型,即(1,2)
函数的嵌套调用
之前学的if、while可以嵌套使用,达到想要的效果,那么函数也是可以嵌套使用~~
>>> def test_1():
... print('this is 1 func')
...
>>> def test_2():
... print('this is 2 func')
... test_1()
... print('this is 2 func2')
...
>>> test_2()
this is 2 func
this is 1 func
this is 2 func2
>>>
上面代码中,在函数test_2中调用test_1函数,当执行完test_1中的函数内容时,继续执行tes_2函数中的内容~
局部变量和全局变量
-
局部变量
def fun_test(): a = 12 print('a是{}'.format(a)) a = 23 print('a是{}'.format(a)) fun_test() def fun_t(): a = 12 print('a是{}'.format(a)) fun_t()
在上面的代码中,定义了一个变量a,这个变量我们称为局部变量。
在第一个函数里面两次打印的函数值是变化的,也就是说第二次打印的时候变量a的值发生了变化,修改了变量a的值~
- 在一个函数内部定义的变量我们称为局部变量
- 不同的函数,可以定义相同的名字的局部变量,但是各用个的不会产生影响
- 局部变量的作用,为了临时保存数据需要在函数中定义变量来进行存储,这就是它的作用
-
全局变量 如果一个变量能在一个函数里面使用,又可以在其他函数 里面使用,这种变量我们称为全局变量
a = 10
def fun_1():
print('a是{}'.format(a))
def fun_2():
print('a是{}'.format(a))
fun_1()
fun_2()
在局部变量中,变量值是可以修改的,那么全局变量,我们怎么修改?
a = 10
def fun_1():
print('a是{}'.format(a))
def fun_2():
global a
a += 1
print('a是{}'.format(a))
fun_1()
fun_2()
- 在函数外边定义的变量叫做全局变量
- 全局变量能够在所有的函数中进行访问
- 如果在函数中修改全局变量,那么就需要使用global进行声明,否则出错
- 如果全局变量的名字和局部变量的名字相同,那么使用的是局部变量
- 在函数中不使用global声明全局变量时不能修改全局变量的本质是不能修改全局变量的指向,即不能将全局变量指向新的数据。
- 对于不可变类型的全局变量来说,因其指向的数据不能修改,所以不使用global时无法修改全局变量。
- 对于可变类型的全局变量来说,因其指向的数据可以修改,所以不使用global时也可修改全局变量。
递归函数
之前说的一个函数可以调用另外一个函数,那么函数自身调用本身的话,这个函数就是递归函数。
- 作用
- 比如说,我们计算阶乘(1✖2✖3✖4✖5)
def fun_d(num): if num >=1: result = num * fun_d(num-1) else: result = 1 return result print(fun_d(5)) # 结果:120
- 比如说,我们计算阶乘(1✖2✖3✖4✖5)
匿名函数
用lambda关键词能创建小型匿名函数,这种函数省略了用def声明函数的标准步骤。
- 语法:
lambda [arg1 [,arg2,.....argn]]:expression # lambda 参数列表:return [表达式] 变量 # 由于lambda返回的是函数对象(构建的是一个函数对象),所以需要定义一个变量去接收
- 代码示例:
sum = lambda arg1, arg2: arg1 + arg2 # 调用sum函数 print("两个数的和是:{}".format(sum(1,2))) # 返回结果:“两个数的和是:3”
- lambda 只是一个表达式,函数体比 def 简单很多。
- lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
- lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。
- 虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。
- Lambda函数能接收任何数量的参数但只能返回一个表达式的值
- 匿名函数不能直接调用print,因为lambda需要一个表达式
- 使用匿名函数
如下数据:
rm = [
{"name":"c", "age":18},
{"name":"e", "age":19},
{"name":"a", "age":17}
]
- 按name排序:
rm.sort(key = lambda x:x['name']) # name 排序是按照字母先后顺序 print(rm) # 返回结果: [{'name': 'a', 'age': 17}, {'name': 'c', 'age': 18}, {'name': 'e', 'age': 19}]
- 按照age排序:
rm.sort(key=lambda x: x['age']) print(rm) # 返回结果: [{'name': 'a', 'age': 17}, {'name': 'c', 'age': 18}, {'name': 'e', 'age': 19}]
思考
请用函数实现一个判断用户输入的年份是否是闰年的程序
- 提示:
- 1.能被400整除的年份
- 2.能被4整除,但是不能被100整除的年份 以上2种方法满足一种即为闰年