一、认识函数
所谓"函数",就是指为一段实现特定功能的代码"取"一个名字,以后即可通过该名字来执行(调用)该函数。
函数是执行特定任务的一段代码,程序通过将一段代码定义成函数,并为该函数指定一个函数名,这样即可在需要的时候多次调用这段代码。函数就是Python程序的重要组成单位,一个Python程序可以由很多个函数组成。
二、定义函数
你可以定义一个由自己想要功能的函数,以下是定义函数简单的规则:
函数代码块以
def
关键词开头,后接函数标识符名称和圆括号**()**
任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数
函数的第一行语句可以选择性的使用文档字符串来用于存放函数的说明信息
函数内容以冒号起始,并且缩进
**return[返回值]**结束函数,选择性的返回一个值给调用方,没有指定返回值时默认为None
语法:
def 函数名(参数列表):
函数体
示例一:打印乘法表
In [7]: def test():
...: for i in range(1,10):
...: for j in range(1,i+1):
...: print("%d*%d=%d"%(j,i,j*i),end=" ")
...: print("")
...: return "打印完毕!"
=== 调用函数 ===
In [8]: test()
1*1=1
1*2=2 2*2=4
1*3=3 2*3=6 3*3=9
1*4=4 2*4=8 3*4=12 4*4=16
1*5=5 2*5=10 3*5=15 4*5=20 5*5=25
1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36
1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49
1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64
1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81
Out[8]: '打印完毕!'
三、函数的参数
函数传参:
在定义Python函数时可以定义参数,定义时的参数称为形参(形式参数的意思),这些形参的值要等到调用该函数时才能确定下来,由函数的调用者负责为形参传入参数值,传入的参数值称为实参(实际参数值)。简单来说,就是谁调用函数,谁负责传入参数值。
示例二:打印学生信息
In [15]: def student(name,age,school):
...: print("You name is %s"%(name))
...: print("You age is %s"%(age))
...: print("You school is %s"%(school))
...:
=== 调用函数并传递name、age、school三个参数 ===
In [16]: stu1 = student("aaa","10","qinhua")
You name is aaa
You age is 10
You school is qinhua
In [16]: stu1 = student("aaa","10","qinhua")
You name is aaa
You age is 10
You school is qinhua
函数的参数类型:
位置参数
:按照形参的位置传入的参数称为位置参数,如果使用位置参数的方式来传入参数,则必须严格按照定义函数时指定的顺序来传入参数值;
关键字参数
:如果是根据参数名来传入参数值,则无须遵守定义形参的顺序,这种方式被称为关键字参数;
默认参数
:在某些情况下,程序需要在定义函数时为一个或多个形参指定默认值,这样在调用函数时就可以省略为该形参传入参数值,而是直接使用该形参的默认值即可;
示例三:打印学生信息
In [18]: def student(sid,name,age,school="qinghua"):
...: print("You sid is %s"%(sid))
...: print("You name is %s"%(name))
...: print("You age is %s"%(age))
...: print("You school is %s"%(school))
...:
...:
=== 调用函数并传入sid、name、age三个参数 ===
In [18]: def student(sid,name,age,school="qinghua"):
...: print("You sid is %s"%(sid))
...: print("You name is %s"%(name))
...: print("You age is %s"%(age))
...: print("You school is %s"%(school))
...:
...:
In [20]: stu4 = student(2,name="ddd",40)
File "", line 1
stu4 = student(2,name="ddd",40)
^
SyntaxError: positional argument follows keyword argument
Python规定:关键字参数必须位于位置参数的后面,带默认值的参数定义在形参列表的最后。
可变位置参数
:Python允许定义个数可变的参数,这样可以在调用函数时传入任意多个参数,Python允许在形参前面添加一个星号(*),这样就意味着该参数可以接收多个参数的值,多个参数值被当成元组传入。
示例四:打印各科课本
In [21]: def test(*args):
...: for i in args:
...: print("书本名称为:%s"%(i))
...:
=== 调用函数并传入多个参数 ===
In [22]: books = test("数学","语文","英语")
书本名称为:数学
书本名称为:语文
书本名称为:英语
可变关键字参数
:Python还可以收集关键字参数,此时Python会将这种关键字参数收集成字典,为了让Python能收集关键字参数,需要在参数前面添加两个星号(**)。
示例五:打印学生分数
In [47]: def test(*args,**kwargs):
...: name = args[0]
...: age = args[1]
...: dic = kwargs
...: print("You Name is %s"%(name))
...: print("You Age is %s"%(age))
...: print("You fraction is %s"%(dic))
=== 调用函数并依次传入位置参数和关键字参数 ===
In [48]: std01 = test("ddd","20",语文=89,英语=78,数学=90)
You Name is ddd
You Age is 20
You fraction is {'语文': 89, '英语': 78, '数学': 90}
In [49]: std02 = test("eee","20",语文=90,英语=79,数学=80)
You Name is eee
You Age is 20
You fraction is {'语文': 90, '英语': 79, '数学': 80}
四、变量作业域
在程序中定义一个变量时,这个变量是有作业范围的,变量的作用范围被称为它的作用域,根据定义变量的位置,变量分为两种:
局部变量
:在函数中定义的变量,包括参数,都被称为局部变量;
全局变量
:在函数外面、全局范围内定义的变量,被称为全局变量;
每个函数在执行时,系统都会为该函数分配一块"临时内存空间",所有的局部变量都被保存在这块临时内存空间内。当函数执行完成后,这块内存空间就释放了,这些局部变量也就失效了,因此离开函数之后就不能再访问局部变量了。全局变量意味着它们可以在所有函数内被访问;当局部变量呵全局变量的值相同时,局部变量优先被访问。
Python提供了三个工具函数来获取指定范围内的"变量字典":
globals()
:该函数返回当前局部范围内所有变量组成的"变量字典";
locals()
:该函数返回当前局部范围内所有变量组成的"变量字典";
vars(object)
:获取在指定对象范围内所有变量组成的"变量字典",如果不传入object参数,vars()和locals()的作用完全相同;
示例六:打印局部变量和全局变量
In [1]: name,age = "aaa",20//定义全局变量
In [2]: def test():
...: name = "bbb"
...: age = 30//定义局部变量
...: print(locals())
...: print(globals())
In [3]: test()
{ '_i1': 'name,age = "aaa",20'}
globals()和locals()的区别与联系
:
locals()总是获取当前局部范围内所有变量组成的"变量字典",因此,如果在全局范围内(在函数之外)调用locals()函数,同样会获取全局范围内所有变量组成的"变量字典";而globals()无论在哪里执行,总是获取全局范围内所有变量组成的"变量字典";
一般来说,使用locals()和globals()获取的"变量字典"只应该被访问,不应该被修改,但是实际上,不管是使用globals()还是locals()获取的全局范围内的"变量字典",都可以被修改,而这种修改会真正改变全局变量本身;但通过locals()获取的局部范围内的"变量字典",即使对它修改了也不会影响局部变量;
五、匿名函数
Python使用lambda来创建匿名函数,所谓匿名,即不再使用def语句来定义一个函数;
lambda只是一个表达式,函数体比def简单很多;
lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去;
lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数;
虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率;
lambda表达式的语法格式如下:
lambda [parameter_list]: 表达式
从上面的语法格式可以看出lambda表达式的几个要点:
lambda表达式必须使用lambda关键字定义;
在lambda关键字之后、冒号左边的是参数列表,可以没有参数,也可以有多个参数;如果有多个参数,则需要多个逗号隔开,冒号右边是该lambda表达式的返回值;
示例七:求乘方积
In [20]: test = lambda x,y : x**y
In [21]: test(2,3)
Out[21]: 8
lambda表达式的好处:
对于单行函数,使用lambda表达式可以省去定义函数的过程,让代码更加简洁;
对于不需要多次复用的函数,使用lambda表达式可以在用完之后立即释放,提高了性能;