目录
函数定义
函数是带名字的代码块,用于完成具体的工作,当在程序中多次执行同一项任务时,可以编写一个执行该任务的函数,在使用时只需调用即可,无需反复的编写完成该任务的代码。
结构
def 函数名():
'''函数说明'''
代码块
def name(): #函数名字
'''
这是对函数的注释说明
:return:
'''
print('hello world')
return #表示返回值,默认为None
其中函数名的定义方式和变量的定义方法一样,只能由字母、数字、下划线组成等。
函数的调用
依次指定函数名以及用括号括起来的必要信息即可。
def name():
'''
这是对函数的注释说明
:return:
'''
print('hello world')
return
name() #调用上面定义号的函数
#输出结果hello world
return
翻译为:返回
定义的函数执行时遇到return时结束,不会再执行下面的代码
- 如果return什么都不写或者没有写return,返回的结果就是None
- 如果return后面写了一个值,返回给调用者这个值
- 如果return后面写了多个值,返回给调用者一个tuple(元组), 调用者可以直接使用解构获取多个变量
def content1():
'''
如果return什么都不写或者没有写return,返回的结果就是None
:return:
'''
return
def content2():
'''
如果return后面写了一个值,返回给调用者这个值
:return:
'''
return 1
def content3():
'''
如果return后面写了多个值,返回给调用者一个tuple(元组), 调用者可以直接使用解构获取多个变量
:return:
'''
return 1,2,3
print('返回值不填时:',content1()) #输出结果为返回值不填时: None
print('当返回值有一个值时:',content2()) #输出结果为当返回值有一个值时: 1
print('当返回值有多个值时:',content3()) #输出结果为当返回值有多个值时: (1, 2, 3)
函数的参数
函数名后面括号里面的就是函数的参数!
参数又分为了实际参数和形式参数,给函数传递信息的时候将实际参数交给形式参数的过程被称为传参!
实际参数
在函数调用的时候给函数传递的值,实际执行的时候给函数传递的信息,表示给函数具体的内容
形式参数
写在函数声明的位置的变量叫形参,形式上面是一个完整,表示这个函数需要的具体内容
def area(a,b): #在这里的a、b就是形式参数
'''
计算长方形的面积
:param a: 表示长方形的边
:param b: 表示长方形的另一条边
:return:
'''
s=a*b
return s #将计算后的面积返回出来
s=area(5,10)#当调用函数时的就是实际参数,s表示接受函数返回的面积值
print('变成为5、10的长方形面积是:',s) #输出结果为变成为5、10的长方形面积是: 50
参数的分类
位置参数
是在传参时,实际参数与形式参数位置一一对应的就是位置参数
def area(a,b):
'''
计算长方形的面积
:param a: 表示长方形的边
:param b: 表示长方形的另一条边
:return:
'''
print('a=',a) #输出结果为a= 5
print('b=',b) #输出结果为b= 10
s=a*b
return s
s=area(5,10)
print('变成为5、10的长方形面积是:',s)
当实际参数调换位置后
def area(a,b):
'''
计算长方形的面积
:param a: 表示长方形的边
:param b: 表示长方形的另一条边
:return:
'''
print('a=',a) #输出结果为a= 10
print('b=',b) #输出结果为b= 5
s=a*b
return s
s=area(10,5)
print('变成为5、10的长方形面积是:',s)
关键字参数
是在输入实际参数是指定变量名的参数
def area(a,b):
'''
计算长方形的面积
:param a: 表示长方形的边
:param b: 表示长方形的另一条边
:return:
'''
print('a=',a) #输出结果为a= 5
print('b=',b) #输出结果为b= 10
s=a*b
return s
s=area(a=5,b=10)
print('变成为5、10的长方形面积是:',s)
当实际参数调换位置后
def area(a,b):
'''
计算长方形的面积
:param a: 表示长方形的边
:param b: 表示长方形的另一条边
:return:
'''
print('a=',a) #输出结果为a= 5
print('b=',b) #输出结果为b= 10
s=a*b
return s
s=area(b=10,a=5)
print('变成为5、10的长方形面积是:',s)
调换位置后参数的值不会发生改变
混合参数
是在传实际参数是位置参数和关键字参数都使用了,但是位置参数必须在关键字参数的前面
def sum(a,b,c):
'''
计算三个数的总和
:param a:
:param b:
:param c:
:return:
'''
print('a=',a,'b=',b,'c=',c)#输出结果是a= 1 b= 2 c= 3
s=a+b+c
return s
d=sum(1,2,c=3) #在这里的参数计算混合参数
print('总和为',d) #输出结果是总和为 6
如果关键字参数在位置参数前面时,则会报错 SyntaxError: invalid decimal literal
默认值参数
是在定义形式参数时就定义好的参数,在调用时可以不输入也可以正常运行,如果在实际参数中输入的默认参数的值,则会按照输入后值进行运行
def sum(a,b,c=3): #默认参数c=3
'''
计算三个数的总和
:param a:
:param b:
:param c:
:return:
'''
print('a=',a,'b=',b,'c=',c)#输出结果是a= 1 b= 2 c= 3
s=a+b+c
return s
d=sum(1,2) #只需要输入a、b的值即可
print('总和为',d) #输出结果是总和为 6
修改后
def sum(a,b,c=3): #默认参数c=3
'''
计算三个数的总和
:param a:
:param b:
:param c:
:return:
'''
print('a=',a,'b=',b,'c=',c)#输出结果是a= 1 b= 2 c= 5
s=a+b+c
return s
d=sum(1,2,5) #对默认参数进行了修改
print('总和为',d) #输出结果是总和为 8
修改默认参数使用位置参数和关键字参数都可以。
动态接受位置参数
简单说就是在输入在实际参数中输入多个参数,在传参过程中将参数打包成列表、元组等数据类型。
使用一个单星号(*)号,表示打包和解包列表、元组等数据时
def sum(*a): #对传入参数进行打包
print(type(a)) #<class 'tuple'>
print(a) #输出结果为(1, 2, 5)
print(*a) #对数据进行解包,输出结果为1 2 5
d=sum(1,2,5) #传入多个值
其中单*用于元组和列表的打包和解包必须使用非关键字参数!否则会报错 TypeError: sum() got an unexpected keyword argument
动态接受关键字参数
与动态接受位置参数类似,但是动态接受关键字参数是将参数打包成字典。使用双星号(**)表示,在使用中必须使用关键字参数
def sum(**a): # 对传入参数进行打包
print(type(a)) # <class 'tuple'>
print(a) # 输出结果为{'name': 1, 'hh': 2}
d = sum(name=1,hh=2) # 传入多个值
动态接受关键字参数是无法进行解包的!
在定义函数时的*号或者**号为打包
在函数体内的*号或者**号为解包
形式参数的顺序
位置参数>动态位置参数>默认值参数>关键字参数>动态关键字参数
命名空间
存放名字和值的关系的空间称为: 命名空间.
命名空间的分类
全局命名空间:我们直接在python文件中,函数外声明的变量都属于全局命名空间
局部命名空间:在函数中声明的变量会放在局部命名空间
内置命名空间:存放python解释器为我们提供的名字,
使用下列代码可查看内置的命名空间
import builtins
print(dir(builtins))
命名空间的加载顺序:
电脑在加载命名空间时会有一个固定的加载顺序:
内置命名空间 --> 全局命名空间 --> 局部命名空间(函数被执行的时候)
取值顺序
取值顺序也与加载顺序一样
局部命名空间>全局命名空间>内置命名空间
变量的作用域
在不同的位置定义的变量它的作用范围是不同的,根据作用范围划分共有两种:全局作用域 和 局部作用域。
全局作用域:
包括内置命名空间和全局作用空间.在整个文件的任何位置都可以使用(遵循从上到下逐行执行)。它的命名空间为全局命名空间+内置命名空间
局部作用域
在函数内部可以使用 ,当该函数运行结束时,内部的变量都会被系统删除。 它的命名空间为局部命名空间。
global (全局声明变量)
使用global时,则可以在函数内部修改全局的变量,如果全部不存在的话就会创建一个变量
没有使用gloabal时,在函数里面对变量a进行修改并没有对全局变量a进行改变
a=20 #全局变量
def name():
a=30 #局部变量
print(a)
name()
print(a)
'''
输出结果为
30
20
'''
使用后
a=20 #全局变量
def name():
global a
a=30 #局部变量
print(a)
name()
print(a)
'''
输出结果为
30
30
'''
注意:使用nonlocal改变全局变量时,nonlocal 变量这段代码必须放在这个变量使用前的位置,不可以先调用过这个变量,然后再进行声明修改,否则会报错
nonlocal(非局部声明变量 )
使用nonlocal时,只修改上一层变量,如果上一层没有变量就往上找一层,只会找到函数的最外层,不会找到全局进行修改。由于它改变的是上一次函数中的变量,所以只能在嵌套函数中使用它。
使用前,每个函数体内部的局部变量互不影响。
a=20 #全局变量的a
def name():
a=15 #第一层函数中的局部变量a
def name1():
a=30 #最里一层的局部变量a
print('函数嵌套内部的a为',a)
name1()
print('函数外部的a为',a)
name()
print('全局变量中的a',a)
'''
输出结果为
函数嵌套内部的a为 30
函数外部的a为 15
全局变量中的a 20
'''
使用后最内部的a因为nonlocal,所以对第一层函数中的局部变量a进行了修改,而全局变量a并没有发生改变。
a=20 #全局变量的a
def name():
a=15 #第一层函数中的局部变量a
def name1():
nonlocal a
a=30 #最里一层的局部变量a
print('函数嵌套内部的a为',a)
name1()
print('函数外部的a为',a)
name()
print('全局变量中的a',a)
'''
输出结果为
函数嵌套内部的a为 30
函数外部的a为 30
全局变量中的a 20
'''