昨日回顾
函数的定义
定义函数阶段只检测语法,不执行代码
def 函数名():
代码块
函数的三种定义方式
空函数
def func():
pass
有参函数
def foo(x,y):
代码块
无参函数
def foo():
代码块
函数的返回值
1.return可以返回值,默认返回None,return后面不加东西也返回None
2.return可以终止函数,有多个return,执行到第一个就结束
3.return可以返回多个值,以元组形式返回
函数的调用
函数调用就会执行代码
函数名()
函数的参数
形参
接受实参,具有描述意义
位置形参
从左到右依次接受位置实参
默认形参
1.具有默认值,如果传惨,使用传参的值;否则使用默认值(形参会多次使用同一个值)
2.默认形参必须得放在位置形参后面
实参
具体得值,传值给形参
位置实参
从左到右依次传惨给位置形参
关键字实参
1.按照形参名传参(参数较多得情况使用该方法)
2.关键字实参必须得在位置实参得后面
今日内容
可变长参数
*
*形参名
def f1(*args):#调用函数时,有多少个位置实参,我就接受多少个参数
print(args)
f1()#空元组
*args(约定俗成得),用元组接受多余得位置实参
*实参
def f1(a, b, c, e, d, f, g):
print(a, b, c, e, d, f, g)
lt = [1, 2, 3, 4, 5, 6, 7]# f1(lt[0],lt[1],lt[2],lt[3],lt[4],lt[5],lt[6])
f1(*lt) # *lt把列表中的元素打散成位置实参依次传给位置形参
**
**形参
def f1(**kwargs):
print(kwargs)
f1()#空字典
**kwargs用字典接受多余得关键字实参
**实参
def f1(z, b):
print(z, b)
dic = {'z': 1, 'b': 2} # a=1,b=2
f1(**dic) # **dic把字典打散成关键字实参然后传给函数f1
函数对象
python中一切皆对象
s=10
print(s)
1.引用
s1=s
2.容器元素
lt=[s]
3.作为函数的实参
def f1(s):
print(s)
4.作为函数的返回值
def f1(s):
return s
字典/列表/元组/集合/布尔值,所有对象都可以做以上四件事
函数对象==函数名 函数名()就是在调用,没有其他意思
函数嵌套
函数里面有函数
def f1():
print('from f1')
def f2():
print('from f2')
res=f1()
函数内部定义的函数,外部就不能用
名称空间和作用域
变量名/函数名--》名称--》名称空间:专门存储名称的
内置名称空间:存储了内置方法的名称
数据类型自带内置方法;python解释器自带内置方法(print/len/list/str/dict)
全局名称空间:除了内置和局部都叫全局
局部名称空间:函数内部定义的都叫局部
名称空间的执行(生成)循序:
1.内置名称空间:python解释器启动的时候就有了
2.全局名称空间:执行文件代码的时候才会有全局
3.局部名称空间:函数调用的时候才会有局部
搜索顺序
先从当前所在位置寻找,找不到再按找这种循序,不会逆着方向寻找
局部——》全局——》内置——》报错
作用域
全局作用域:内置名称空间+全局名称空间——》全局作用域
1.全局作用域的x和局部作用域的x没有半毛钱关系
局部作用域:局部名称空间——》局部名称空间
2.局部作用域1的x和局部作用域2的x也没有任何关系,即使局部作用域1和局部作用域2在同一个局部作用域下
global
x = 10
def f1():
global x # 让global以下的局部的x变成全局的x
x = 20
f1()
print(x)
nonlocal
x = 10
def f1():
def f2():
def f3():
nonlocal x # nonlocal让x成为顶层函数的局部,不是让他成为全局 # 压根没有应用情景,尽量不要嵌套函数
x = 1
x = 2
f3()
print(1, x)
f2()
f1()
print(2,x)
def f0():
x = 3 # f1的nonlocal无法修改
f1()
所有可变数据类型均可打破上述一切规则
lt = [10]
def f1():
lt.append(12)
lt[0] = 11
f1()
print(lt)