python笔记(9)--函数(参数,作用域,函数嵌套)
目录内容
- 参数
- 作用域
- 函数嵌套
内容详细:
time.sleep()的用法:
import time #使用time模块
result = [1,1]
while True:
num = result[-1] + result[-2]
result.append(num)
if result[-1] >= 100:
break
print(result)
time.sleep(1) # 设置time睡眠时间,每隔一秒打印一次
1.参数
基本参数
- 任意个数
- 任意类型
def func(a1,a2,a3):
print(a1,a2,a3)
func(1,"sadf",True)
位置传参
- 调用函数并传入参数
def func(a1,a2)
print(a1,a2)
func(1,2)
关键字传参
- 关键字传参数可以和位置参数混合使用
- 位置传入的参数在前 > 关键字参数在后 == 总参数个数 (永远遵循此规则)
def func(a1,a2):
print(a1,a2)
func(a2=1,a1=2)
#示例:
def func(a1,a2,a3):
print(a1,a2,a3)
#func(a2=1,a1=2,a3=3)
#func(1,a2=2,a3=3)
#func(a1=1,a2=2,3) 错误,位置参数应在前,关键字参数应在后,
#func(1,a2=2,3) 错误,位置参数应在前,关键字参数应在后,
默认参数
- 调用函数时,默认参数可传可不传
- 默认参数规则放后面
def func(a1,a2=2,a3=3):
print(a1,a2,a3)
#func(a1=1,a2=2,a3=333)
#func(1)
万能参数(参数打散)
- *args(规范使用此变量命名)
-
可接收任意个数的位置参数,并将参数转换成元组。
- 函数调用有*,传参会把值打散了传入args元组内,变成元组的各个元素
- 函数调用无*,传参会把值作为args的第0个元素传入
-
只能用位置参数传参
def func(*args):
print(args)
#func(1,22,33,(1,2,3),["asf",789],"oiquwer") 都可传入一个值的args,args为(传入值组成的元组tuple)
#func(*(11,22,33)) 结果为(11,22,33)
#func((11,22,33)) 结果为((11,22,33))
def func(a1,*args):
print(a1,args)
# func(1,(11,22,33)) 结果为1,(11,22,33)
# func(1,2,3,4,5,6) 结果为1,(2,3,4,5,6)
- **kwargs(规范使用此变量命名)
-
可接收任意个数的关键字参数,并将参数转换为键值对放入字典中
- 函数调用有
*(必须为两个*
),只能传字典,值为传入的字典 - 函数调用无*,根据关键字传参,会直接生成键值对加入字典
- 函数调用有
-
只能用关键字参数传参
def func(**kwargs):
print(kwargs)
func(k1=1,k2="asdf") #结果为 {'k1': 1, 'k2': 'asdf'}
func(**{"k1":1,"k2":"asdf"}) #结果为 {'k1': 1, 'k2': 'asdf'}
- 混合使用
-
可接收任意参数(位置参数+关键字参数)
def func(*args,**kwargs): print(args,kwargs) func(1,2,3,k1=55,k2=89) #结果为(1,2,3) {'k1':55,'k2':89} func(*[1,2,3],k1=55,k2=89) #结果为(1,2,3) {'k1':55,'k2':89} func(*[1,2,3],**{"k1":55,"k2":89}) #结果为(1,2,3) {"k1":55,"k2":89} func(11,22,*[1,2,3],k1=55,k2=89,**{"k11":55,"k12":89}) #结果为(11, 22, 1, 2, 3) {'k1': 55, 'k2': 89, 'k11': 55, 'k12': 89}
参数重点(掌握)
- 定义函数(以后常见的函数样式)
def func1(a1,a2):
pass
def func2(a1,a2=None):
pass
def func3(*args,**kwargs):
pass
-
调用函数(传参)
一定要记住,位置参数在前,关键字参数在后
2.作用域
python中:
-
py文件:全局作用域
-
函数:局部作用域
a=1 def func(): x1=666 print(x1) print(a) print(b) b=2 func() # 666,1,2 print("----------分界线1----------") a = 8888 def func2(): print(a,b) #从上往下执行,如果函数体内有变量在全局更改了,则执行到调用函数的前面才重新赋值 func() func2() #报错,因为从上往下执行中,b没有值 b=2222 print("----------分界线2----------")
#从上往下执行,如果函数体内有变量在全局更改了,则执行到调用函数的前面才重新赋值 a=1 def func(): x1=666 print(x1) print(a) print(b) b=2 b=222 func() #调用函数时,输出结果为x1=666,a=1,b=222 b=8888 print(b) #输出结果为8888
#错误示例 def func(): x1=666 print(x1) func() print(x1) #因为x1的作用域在函数体中,全局调用不了函数体内局部作用域的赋值
-
总结:
-
一个函数就是一个作用域
-
作用域中查找数据规则:优先在自己的作用域找数据,自己没有就去 "父级" -> 全局作用域 去找,全局里没有就报错
- 注意:父级作用域中的值到底是什么
x = 11 def func(): x = 8 print(x) #8 def x1(): print(x) #8 x1() x = 9 x1() #9 x = 10 print(x) #10 func()
-
子级作用域中重新赋值,不会影响到父级和全局的变量赋值
-
子级作用域中修改可变类型变量,则会影响到父级和全局的可变变量值
info = [11,22] def func(): info.append(33) print(info) func() #结果为[11,22,33]
-
global:在局部变量中强制赋值,修改全局变量
name = "yanan" def func(): global name name = "alec" func() print(name) #输出结果为name = alec ####################################### name = ['wo','yanan'] def func(): global name name = "alec" func() print(name) #输出结果为name = alec ########嵌套内的函数中,global修改的也是全局变量 name = "yanan" def func(): name = "centos" def inner(): global name name = 999 print("inner",name) #name = 999 inner() print("func",name) #name = centos func() print("全局变量",name) #name = 999(被global修改过的变量)
-
nolocal:只能用在嵌套函数中,嵌套函数中只修改上层的赋值
name = "yanan" def func(): name = "centos" def inner(): nonlocal name name = 999 print("inner",name) #name = 999 inner() print("func",name) #name = 999(被nonlocal修改过的变量) func() print("全局变量",name) #name = "yanan"(全局未被修改)
-
全局变量由大写字母组成,函数体内部可由小写字母组成。类似于以下代码
USER_LIST = [11,22,33] def func(): USER_LIST.append(44) USER_LIST.append(550) func() print(USER_LIST)
-