定义函数并进行变量调用
定义两个参数的例子
形式参数:比如name和times(占坑位)
实际参数:是在调用过程中实际传入的值,比如6和TS
函数的返回值
或
但除数不能为0,修改代码
注意:只要执行到了return语句函数就会立刻返回而不会理会后面是否还有其他语句
如果一个函数没有通过return语句显示的来返回内容,那么它会在自己执行完函数体中的所有语句之后悄悄返回一个none
参数
位置参数:
有时也称必备参数,指的是必须按照正确的顺序将实际参数传到函数中,换句话说,调用函数时传入实际参数的数量和位置都必须和定义函数时保持一致。
关键字参数:
关键字参数是指使用形式参数的名字来确定输入的参数值。通过此方式指定函数实参时,不再需要与形参的位置完全一致,只要将参数名写正确即可。
默认参数:
在调用函数时如果不指定某个参数,Python 解释器会抛出异常。为了解决这个问题,Python 允许为参数设置默认值,即在定义函数时,直接给形式参数指定一个默认值。这样的话,即便调用函数时没有给拥有默认值的形参传递参数,该参数可以直接使用定义函数时设置的默认值。
最后一个值不给出,编译器默认为o=“鱼”
指定有默认值的形式参数必须在所有没默认值参数的最后,否则会产生语法错误。
若传递了第三个参数,就会覆盖原来的默认值
斜杠左边表示必须传递位置参数而不能是关键字参数:
报错啦!
再看几个例子吧
限制只能使用关键字参数的语法
*表示左侧既可以是关键字参数也可以是位置参数,但是右侧只能是关键字参数才不会报错
收集参数
python的函数支持可变不定数量的参数模式,这种将不定数量实参在调用时传递给函数,函数将其识别并保存到指定形参的过程称为参数收集
带一个星号的参数收集模式
这种模式是在函数定义时在某个形参前面加一个星号,调用时按位置匹配不带星号的形参和实参,多余的实参都将作为一个元组的元素保存到星号对应的形参中,该星号后的形参就称为收集参数。
这种模式的参数收集过程与序列解包类似,只是序列解包是将序列中多出的部分存放到星号后面的列表变量,而函数收集是将多出的参数存放到收集参数对应的元组变量。这种模式的参数收集与序列解包类似,收集参数最好是最后一个形参,但可以出现在函数参数的任何位置,只是此时该参数后面的参数在调用时必须用关键字参数模式传值,否则这些实参值都将作为收集参数的一部分。
定义方法
形参打印出来
函数可返回多个值
通过*号实现打包的操作,将多个参数打包到一个元组里
如果在收集参数后面还需要指定其他参数
那么在调用函数时就应该使用关键字参数来指定后面的参数。。。。
报错: 函数在传递参数的过程中缺少了为a和b两个参数传递实参的过程
给a和b使用关键字参数传递一下
看这个例子
1的值给了a
2,3,4以元组的形式给了b
x=5,y=6给了打包成字典形式的收集参数c
字符串的format方法同时拥有两种收集参数:有字典型和元组型
解包参数
在使用*时:在形参的使用时称为参数的打包;在实参的使用称为解包参数
一个*时
两个*时
作用域
作用域:变量可以被访问的范围,一个变量的作用域总是由它在代码中被赋值的位置来决定的
局部作用域:如果一个变量定义的位置是在函数的里面那么它的作用域就仅限于该函数中
全局作用域:
如果在任意一个函数外部定义一个变量,那么它的作用于就是全局的,也称为全局变量
如果函数内部和外部都有一个变量x但值不同,局部变量会覆盖同名的全局变量
查看id 发现如果多了一个x=520(局部变量覆盖全局变量了)那么id的值就不一样了
全局变量可以在函数的内部被访问到,但是无法在函数中修改它的值,若要修改它会创建一个同名的局部变量进行覆盖,会报错
global语句
在函数内部修改全局变量的值
用了global语句就是明确告诉编译器需要修改全局变量的值
嵌套函数
先看这个函数调用过程
将函数f2嵌套进f1中的例子
nonlocal语句
实现在函数内部修改函数外部的值
它和global的不同之处在于,nonlocal应用于一个嵌套的函数的作用域中修改名称,而不是所有def之外的全局模块作用域;而且在声明nonlocal名称的时候,它必须已经存在于该嵌套函数的作用域中,它们可能只存在于嵌套的函数中,并且不能由一个嵌套的def中的第一次赋值创建。
LEGB规则(记忆legB 胳膊B)
Local 局部作用域 函数内的名字空间
Enclosed 嵌套函数的外层函数作用域 嵌套函数中外部函数的名字空间
Global 全局作用域 函数定义所在模块的名字空间
Built-in 内置作用域 python内置模块的名字空间
变量的查找顺序是L->E->G->B(点击就看!这个大佬写的能看懂!!!)
放一个图吧
在代码中可能出现变量名字一样,作用域不同的变量引用
不要取一些与内置函数相同的变量名,不然会被覆盖
不通过funA()间接使用funny调用到funB()
函数闭包
闭包的作用:保证数据安全
内层函数对外层函数非全局变量的引用就会形成闭包
被引用的非全局变量也称自由变量,这个自由变量会与内层函数产生一个绑定关系
自由变量不会在内存中消失
例如:比特币的收盘价
第一天6000,第二天7000,第三天8000,第n天的收盘价为:前n天价格之和除以n
li是一个全局变量,在任何位置都可以修改,数据十分不安全
故将程序升级,将li隐藏起来,将其放进函数内,在全局内使其不会被任意修改
但是,函数执行结束之后所有的局部变量都会释放,保存这个值就需要使用闭包
def average():
li = [] #li为自由变量,函数结束后不会在内存中消失
def inner(value):
li.append(value)
return sum(li)/len(li)
return inner
avg = average() #用avg的结果是inner 用avg来保存结果
print(avg(6000))
print(avg(7000))
print(avg(8000))