函数
代码得是一种组织形式
函数是对功能的封装—一个函数一般完成一项特定的功能
函数的使用:
- 函数需要先定义
- 使用函数俗称
调用
语法:
def 函数名(形参列表):
函数体(代码块. return)
调用:
函数名(实参列表)
# 定义一个函数
# 只是定义的话不会执行
# 1 . def是关键字
# 2 . 遵循命名规则,约定俗成,不使用大驼峰
# 3 . 括号和冒号不能省,括号内可以有参数
def func():
print(
"我是一个函数")
print(
"我要完成一定的功能")
print(
"我结束了")
"""多行注释"""
def func(a, b):
""" 这个函数的功能是什么 :param a: 形参a的意义 :param b: 形参b的意义 :return: 返回的是什么东西 """ print(func.__doc__) # 读取函数文档
1. 返回值
return: 在函数执行的时候.如果遇到return.直接返回
1. 如果函数什么都不写,不写return,没有返回值.得到的是None
2. 在函数中写return值,返回一个值
3. 在函数中间或者末尾写return,返回的是None
4. 在函数中可以返回多个返回值.return值1, 值2, 值3, ……接受的是元组
1 # return语句的基本使用
2 # 函数打完招呼后返回一句话
3 def hello(person):
4 print(
"{0}你肿么了?".format(person))
5 print(
"Sir,你不理我了吗?")
6
7 return"我已近跟{0}打招呼了".format(person)
8 p =
"小仙女"
9 rst =
hello(p)
10
11 print(rst)
1 # return案例2
2 # 函数打完招呼后返回一句话
3 def hello(person):
4 print(
"{0}你肿么了?".format(person))
5 return(
"哈哈{0},我先走啦".format(person))
6 print(
"Sir,你不理我了吗?")
7
8 return"我已近跟{0}打招呼了".format(person)
9 p =
"小仙女"
10 rst =
hello(p)
11
12 print(rst)
2. 参数
函数执行的时候给函数传递信息
* 形参:函数声明的位置的变量,在函数定义的时候用到的参数,没有具体的值,只是一个占位发号
* 实参: 函数调用的时候给的具体的值
传参:把实参交给形参的过程
2.1 实参:
1. 位置参数,按照形参的参数位置给形参传值
2. 关键字参数,按照形参的名字给形参传值
3. 混合参数。即用位置参数,也用关键字参数
2.2 形参:
1. 位置参数
2. 默认值参数,先位置后默认值
3. 动态参数
1 # 参数的定义和使用
2
3 def hello(person):
4 print(
"{0}你肿么了?".format(person))
5 print(
"Sir,你不理我了吗?")
6
7 p =
"小仙女"
8 hello(p)
3. 函数的动态参数
*argue位置参数动态传递
在这里表示接收位置参数的动态传参,接收到的是元组
*args表示任何多个位置参数,他是一个tuple;
**kwargue关键字参数的动态传递
在这里表示接受关键字参数的动态传参,接受到的是字典
**kwargue 表示任何多个关键字参数,他是一个dict。并且同时使用*argue和**kwargue时,必须*args参数要在**kwargs前。
**kwarg有一个很漂亮的用法:
1 def kw_dict(**
kwargs):
2 return kwargs
3 print kw_dict(a = 1, b = 2, c = 3
)
4 ==> {
'a':1,
'b':2,
'c'::3}
其实python中就带了dict类,使用dict(a=1, b=2, c=3)即可创建一个字典
顺序: 位置参数 >> *argue >> 默认值参数 >> **kwargue
1 # 可以接受所有的参数的函数
2 def func(*argue, **
kwargue):
3 pass
形参的位置(*,**):聚合
实参的位置(*,**):打散 在实参位置上给一个序列、列表、可迭代对象前面加上*表示把这个序列按顺序打散,如果是一个字典则需要两个*
4. 命名空间
在python解释器开始执⾏之后, 就会在内存中开辟⼀个空间, 每当遇到⼀个变量的时候, 就 把变量名和值之间的关系记录下来, 但是当遇到函数定义的时候, 解释器只是把函数名读入内 存, 表⽰这个函数存在了, ⾄于函数内部的变量和逻辑, 解释器是不关⼼的. 也就是说⼀开始 的时候函数只是加载进来, 仅此⽽已, 只有当函数被调⽤和访问的时候, 解释器才会根据函数 内部声明的变量来进⾏开辟变量的内部空间. 随着函数执⾏完毕, 这些函数内部变量占⽤的空 间也会随着函数执⾏完毕⽽被清空。
命名空间:存放名字和值关系的空间。
分类:
1. 内置名称空间 — 存放 python解释器为我们提供的名字,list、tuple、str等这些都是内置命名空间
2. 全局名称空间 — 我们直接在py文件中,函数外声明的变量都属于全局命名空间,包括最外层的函数命名也属于全局名称空间
3. 局部名称空间 — 在函数中声明的变量会放在局部命名空间
加载顺序:
- 内置命名空间
- 全局命名空间
- 局部命名空间(函数被执行的时候)
取值顺序:
- 局部命名空间
- 全局命名空间
- 内置命名空间
作用域:
作用域就是作用范围,按照生效的范围来看分为全局作用域和局部作用域
1.全局作用域:内置+全局 在整个文件的任何位置都可以使用(遵循由上到下逐行执行)
2. 局部作用域: 局部(当函数被调用的时候) 在函数内部可以使用
globals():查看全局中的内容
loca0ls():查看当前局部作用域中的变量和函数信息
1 a = 10
2 def func():
3 a = 40
4 b = 20
5 def abc():
6 print(
"这是函数的嵌套")
7 print(a, b)
# 这里使用的是局部作用域
8 print(globals())
# 打印全局作用域中的内容
9 print(locals())
# 打印局部作用域中的内容
5. 函数嵌套
函数可以互相的嵌套:
1 def hano(n,a,b,c):
2 '''
3 汉诺塔的递归实现
4 n:代表几个盘子
5 a:代表第一个塔,开始的塔
6 b:代表第二个塔,中间过度的塔
7 c:代表第三个塔,目标塔
8 '''
9 if n==1
:
10 print(a,
"-->", b)
11 if n==2
:
12 print(a,
"-->", b)
13 print(a,
"-->", c)
14 print(b,
"-->", c)
15 return None
16 #把n-1个盘子,从a塔借助于c塔,挪到b塔上去
17 hano(n-1
,a,c,b)
18 print(a,
"-->",c)
19 #把n-1个盘子,从b塔,借助于a塔,挪到c塔上去
20 hano(n-1
,b,a,c)
21
22 a=
"A"
23 b=
"B"
24 c=
"C"
25 n=1
26 hano(n,a,b,c)
27 n=2
28 hano(n,a,b,c)
29 n=3
30 hano(n,a,b,c)
31 n=5
32 hano(n,a,b,c)
6. global和nonlocal
global:表示不再使用局部作用域中的内容,改用全局作用域中的变量
a = 100
# 全局变量 a
def func():
global a # globa是允许函数中访问目标全局变量 a = 20 #此时才能对全局变量进行更改操作 print(a) # 如果不用globa 只允许函数内对全局变量进行不更改值的操作 比如print func() print(a) # 全局变量在函数体内部被更改 所以此处输出的是28
nonlocal:表示在局部作用域中,调用父级命名空间中的变量(在局部寻找外层函数中离他最近的那个变量)
1 a = 10
2 def func():
3 a = 20
# 4 但是这层的a值不会改变
4 def func2():
5 a = 30
# 3 这个被更改了
6 def func3():
7 nonlocal a
# 1 引进最近的变量a 但是不能是全局作用域中的变量 会报错
8 a = 40
# 2 将父辈函数的a值更改
9 print(a)
# 输出40
10 func3()
11 print(a)
# 输出40
12 func2()
13 print(a)
# 输出20
14 func()
15 print(a)
# 输出全局变量10
转载于:https://www.cnblogs.com/jiumo/p/9445864.html