函数的定义
函数:对代码块和功能进行封装以及函数的调用
函数名的命名规则和变量的一样,调用方法:直接使用函数名+()表示调用 ,
函数调用之后都会有返回值,
- 如果函数中没有return 或return 后面没有添加任何的东西,默认返回的值None ,
- 如果函数有一个值,就是讲直接将return后面的值进行返回,如果含有多个值就会将多个值添加到一个元组中,然后将该元组进行返回,调用者可以直接通过解构获得元组中的每个变量
具体如下:
在定义函数的时候,第一行代码使用多个双引号注释的文字就是该函数的注释的说明,可以通过help(函数名) 查看该函数的说明
def 函数名(形式参数 ):
……函数体….
return something (可以是一个变量或者某个公式,如果没有return 的话,那么默认就是retrun None)
调用
gg = 函数名(实际参数)
定义函数的参数
对于参数的传递的话,有位置参数传递和关键词参数传递和混合传参
位置传参:实参与形参一一对应的方式进行传递
关键字传参:根据实参对应的值进行参数的传递,
混合参数传递:两种传递方式混合在一起使用
注意:在使用混合参数的时候,关键字参数必须在位置参数后面
函数的嵌套调用,
上面中d=0就是设置默认值参数,在函数声明的时候给函数参数的默认值,如果在参数传递的过程中能够传递到具体的值,就会只用具体的值,否则直接使用默认的值
注意:必须先声明位置参数,才能声明默认值参数
动态传参:
动态接收位置参数
在定义函数的时候,在最后的一个变量的前面添加一个* *args表示动态接收位置参数,将多余实际参数(位置参数)添加到元组中
动态接收参数的时候要注意: 动态参数必须在位置参数后面
动态接收关键字参数
*args 只能接收位置参数,好像c=0这种参数是不能接收的,所有这是使用**arges 动态接收关键字参数,接收的字典
在形参中必须的顺序是
位置参数 >*args >默认值参数 > **args
如果想要接收所有的参数:
def gg(*arge,**args):
动态传参的另一种方式
如果在实际参数中含有列表和字典,想要调用的时候,直接将列表或者是字典的元素直接添加到args和kargs中,那么在调用实际参数的时候,在列表的前面添加一个* ,在字典的前面添加两个**
上面就是字典和列表的拆包的过程,将list 和info 拆散之后一个个添加到对应的元组和字典中
函数的嵌套
def printer():
print(‘what you do is easy’)
def haha():
i = 0
while i < 5
printer()
i+=1
printer()
函数命名空间与作用域
每当遇到一个变量的时候, 就把变量名和值之间的关系记录下来, 但是当遇到函数定义的时候, 解释器只是把函数名读入内存, 表示这个函数存在了,只有当函数被调用和访问的时候, 解释器才会根据函数内部声明的变量来进行开辟变量的内部空间. 随着函数执行完毕, 这些函数内部变量占用的空间也会随着函数执行完毕而被清空.
可以通过使用globals() 函数查看全局作⽤用域中的内容, 也可以通过locals()来查看局部作用域的变量和函数信息
在if 中定义的函数,在if语句之外的都可以调用,但是如果在函数内部定义的时候 只是在内部有用,但在函数外部不能生效
enclosing表示的是局部变量的上一级局部变量
如果想要在函数内部修改全局变量,可以通过gobal + 变量名 那么在函数中修改的变量就是直接修改全局变量的值(全局也没有找到这个变量的时候。global 会在局部创建(升华)这个变量,)
如果使用nonlocal +变量 是修改最近的上一级的变量,但是这个上一级变量不能直到全局作用域中,如果在知道全局作用域的第一个局部作用域都没有找到,会直接报错
以下说明,在变量查找的时候,如果在本地(同一级别中)的函数没有找到该变量,就向上一层的函数中查找该变量的名称,如果在上一层能够找到定义的函数,就会直接调用,如果还是没有找到,同理,继续向上查找,知道到达函数的外面,如果在函数的外面还是没有找到,说明这个函数没有定义。
如果把列表和字典当做全局变量()
即使在函数内部没有使用global 进行定义,也可以直接进行使用,直接进行修改和添加(原因是它们是可变类型参数,向数值,字符串,元组等不可变参数,如果在传递之后,修改的效果只能是在局部变量中,也就是在特定的函数中才生效)