目录
可变长参数
两种可变长形参
*形参名
def f1(*args): # 调用函数时,有多少个位置实参,就接收多少个参数,组成元组
print(args)
f1() # 打印结果:() # a是空元组
f1(1) # 打印结果:(1, ) #注意有逗号
f1(1, 2) # 打印结果:(1,2)
f1(1, 2, 3, 3, 4, 5, 5, 6, 7, 7, 7, 7, 7, 7, 7, )
*args (约定俗称的),用元组接收 多余 的位置实参
**形参名
def f1(**kwargs): # 调用函数时,有多少个关键字实参,就接收多少组参数,组成字典
print(kwargs)
f1(x=1) # 打印结果:{} # 空字典
**kwargs,用字典接收多余的关键字实参
两种可变长实参
以下仅作了解
*实参
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(a, b):
print(a, b)
dic = {'a': 1, 'b': 2} # a=1,b=2
f1(**dic) # **dic把字典打散成关键字实参然后传给函数f1
函数对象
python中一切皆对象,函数也可以当作对象,有以下四大功能:
引用(拷贝)
当作容器类元素
当作函数的实参
当作函数的返回值
1、引用
def s(): # 定义函数s
a = 10
print(a)
x = s # 引用函数s
x() # x引用了函数s后也继承了函数的特性
2、当作容器类元素
def s(): # 定义函数s
a = 10
return a
lt = [1,s] # 把函数s当作列表元素
print(lt[1]) # 打印结果为函数s的地址:<function s at 0x000001DBE30F1E18>
print(lt[1]()) # 打印结果为:10
3、作为函数的实参
def s(): # 定义函数s
a = 10
return a
def f1(b): # 定义函数f1,b为形参
c = b() + 5
print(c)
f1(s) # 把函数s当作实参传值给形参b
# 打印结果为:15
4、作为函数的返回值
def s():
print('from s')
def f(a):
"""代码"""
return s # 函数s作为返回值,用于执行完函数f的功能后就返回函数s以供调用
res = f(2)
print(res)
res()
字典/列表/元组/集合/布尔值,所有对象都可以做以上四件事情
函数对象 == 函数名 # 函数名不带()
函数名() # 函数名带括号 就是在调用函数
函数嵌套
for循环的嵌套
打印九九乘法表
for i in range(1,10):
for j in range(i):
print(f'{j+1}*{i}={(j+1)*i}'',end='\t') # \t是制表符,强制对齐
print() # 用于换行,每个i值的j循环完后就换行
打印结果为:
1*1=1
1*2=2 2*2=4
1*3=3 2*3=6 3*3=9
1*4=4 2*4=8 3*4=12 4*4=16
1*5=5 2*5=10 3*5=15 4*5=20 5*5=25
1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36
1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49
1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64
1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81
函数嵌套:函数里边定义函数
函数在调用之前只检测语法,不执行代码
函数内部定义的函数,外部不能调用
函数嵌套调用实例:
def max2(x,y): # 定义第一个函数,
if x > y:
return x
else:
return y
def max4(a,b,c,d): # 定义第二个函数
res1 = max2(a,b) # 调用第一个函数
res2 = max2(c,d) # 调用第一个函数
res3 = max2(res1,res2) # 调用第一个函数
return res3
print(max4(1,2,3,4))
这就是函数的调用,函数max4 里边嵌套调用了 max2 这个函数
名称空间和作用域
名称空间:专门用于存储名称的空间
名称空间主要分为以下三类:
1、内置名称空间:存储了内置方法的名称
数据类型自带内置方法;python解释器自带内置方法(print/len/list/str/dict)
2、全局名称空间:除了内置和局部都叫全局
3、局部名称空间:函数内部定义的都叫局部
名称空间的执行(生成)顺序:
1. 内置名称空间:python解释器启动的时候就有了
2. 全局名称空间:执行文件代码的时候才会有全局
3. 局部名称空间:函数调用的时候才会有局部
搜索顺序:
先从当前所在位置寻找,找不到再按照这种顺序,不会逆着方向寻找 局部 --》 全局 --》 内置 --》 报错
作用域
全局作用域: 内置名称空间+全局名称空间 --》 全局作用域
局部作用域
1. 全局作用域的 x 和局部作用域的 x 没有半毛钱的关系
局部作用域:局部名称空间 --》 局部名称空间
2. 局部作用域1的x和局部作用域2的x也没有任何关系,即使局部作用域1和局部作用域2再同一个局部作用域下
global和nonlocal:仅作了解,尽量不要使用
global:打破了上述的第1点规则
global x # 让global以下的局部的x变成全局的x
nonlocal:打破了上述的第2点规则
nonlocal x # nonlocal让x成为顶层函数的局部,不是让他成为全局 # 压根没有应用情景,尽量不要嵌套函数
可变数据类型不受作用域的限制
定义函数:只检测语法,不执行代码