函数二
一.变量作用域
1.局部变量是函数内部变量,在函数临时保存数据,函数调用完则销毁,在函数外访问即报错
2.全局变量函数内外都可访问,当不同函数都要用到某一变量时,则可使用全局变量
def fun1():a=1print(a)fun1() #1print(a) #函数外调用a会报错
二.修改全局变量
尝试直接修改
x=199def fun2():x=500print(x+2)fun2() #502print(x) #199
可见全局变量x并没有发生改变,fun2()只是修改局部变量
修改全局变量
x=199def fun2():global x #global 关键字声明x是全局变量x=500print(x+2)fun2() #502print(x) #500 #可见已经修改全局变量x
1.global 关键字声明x是全局变量
2.修改全局变量先global,然后再修改
三.多函数程序执行流程
要注意函数执行顺序
x=199def fun1():print(x)def fun2():global xx=500print(x)fun1() #199fun2() #500
区别
x=199def fun1():print(x)def fun2():global xx=500print(x)fun2() #500fun1() #500
四.返回值作函数参数
很简单,得到返回值,然后传递
def fun1():return 20def fun2(num):print(num)x=fun1()fun2(x) #20
五.函数有多个返回值
错误写法
def fun1():return 20return 10s=fun1()print(s) #20 只得到一个返回值
正确写法
def fun1():return 20,10,30s=fun1()print(s) #(20, 10, 30) 返回值默认元组类型
返回值默认元组类型
def fun1():return {20,10,30}s=fun1()print(s) #{10, 20, 30}
返回值可自定义返回集合,列表,元组等类型
六.函数的参数
位置参数
1.调用函数时根据函数定义的参数位置来传递参数
2.因此要注意传递和定义参数的顺序及个数也要一致
def fun1(name,age,gender):print(f'名字是{name},年龄是{age},性别是{gender}')fun1('tom',18,'man')#名字是tom,年龄是18,性别是manfun1('tom',18) #报错
关键字参数
函数调用,通过“键=值”形式指定,可以让函数更加清晰,解除顺序要求
2.有位置参数,位置参数必须放在前面,关键字参数之间不存在顺序
def fun1(name,age,gender):print(f'名字是{name},年龄是{age},性别是{gender}')fun1(name='tom',gender='man',age=18) #名字是tom,年龄是18,性别是manfun1('tom',age=18,gender='man') #名字是tom,年龄是18,性别是manfun1(gender='man',age=18,'tom') #报错
缺省参数
1.缺省参数也叫默认参数,用于定义函数,为参数提供默认值,调用函数时可不传默认参数的值
2.注意:所有位置参数必须出现在默认参数前(默认参数采用关键字参数的写法),包括函数定义和函数调用
3.注意:函数调用时,如果为缺省参数传值则会修改默认参数值;否则依旧使用默认值
def fun1(name,age,gender='man'):print(f'名字是{name},年龄是{age},性别是{gender}')fun1('allen',18) #名字是allen,年龄是18,性别是manfun1('allen',33,'woman') #名字是allen,年龄是33,性别是woman
不定长参数
不定长参数也叫可变参数,用于不确定调用的时候会传递多少各参数(参数可传可不传)的场景。此时,可用包裹(packing)位置参数,或者包裹关键字参数,来进行参数传递,方便许多
二者都是组包的过程
1.包裹位置传递
注意:传进的所有参数都会被args变量收集,它会根据传进参数的位置合并为一个元组,args是元组类型
def fun(*args): #一般使用args,但也可替换为其他单词print(args)fun() #()fun('tom') #('tom',)fun('tom',18) #('tom', 18)
2.包裹关键字传递
注意:kwargs变量收集所有关键字参数传递,并组合为字典
def fun(**kwargs): #kwargs的使用与args类似print(kwargs)fun() #{}fun(name='tom',age=18) #{'name': 'tom', 'age': 18}
七.拆包和交换变量值
拆包:元组
注意根据元组数据个数确定变量个数
def fun():return 10,20ss=fun()print(ss) #(10, 20)#将元组中数据拆开输出num1,num2=fun() #注意根据元组数据个数确定变量个数print(num1) #10print(num2) #20
sum1,sum2,sum3=(10,20,30)print(sum1) #10print(sum2) #20print(sum3) #30或者tuple1=(10,20,30)sum1,sum2,sum3=tuple1print(sum1) #10print(sum2) #20print(sum3) #30
拆包:字典
对字典拆包,取出来的是字典的key
dict1={'name':'tom','age':18}a,b=dict1print(a) #nameprint(b) #age#想要取到value值print(dict1[a]) #tomprint(dict1[b]) #18
交换变量值
方法一:借用第三方存储
b=20c=aa=bb=cprint(a) #20print(b) #10
方法二:
a,b=1,2print(a) #1print(b) #2a,b=b,aprint(a) #2print(b) #1
八.引用
值 靠引用来传递
我们可以用id()来判断两个变量是否为同一个值的引用,我们将id()值理解为呢块内存的地址标识
不可变数据类型,如int
为a的值变,则会开辟新的地址,地址变
a=1b=aprint(id(a)) #140704168124816print(id(b)) #140704168124816a=2print(id(a)) #140704168124848
可变数据类型,如list列表,aa值变,地址不发生改变
aa=[10,20]bb=aaprint(aa) #[10, 20]print(bb) #[10, 20]print(id(aa)) #2192283619720print(id(bb)) #2192283619720aa.append(30)print(aa) #[10, 20, 30] #a发生改变print(bb) #[10, 20, 30] #b也跟着发生改变,列表为可变类型print(id(aa)) #2192283619720 列表是可变类型,因而aa改变地址不变print(id(bb)) #2192283619720 aa与bb地址仍相同
九.引用当实参
int不可变
def test(a):print(a) #100print(id(a)) #140704389770736a+=aprint(a) #200print(id(a)) #140704389773936b=100test(b)
输出
100140704389770736200140704389773936
list可变
def test(a):print(a) #100print(id(a)) #140704389770736a+=aprint(a) #200print(id(a)) #140704389773936c=[11,22]test(c)
输出
[11, 22]2268836221320[11, 22, 11, 22]2268836221320
十.可变和不可变类型
数据能直接修改则为可变类型,否则不可变
可变类型
列表
字典
集合
不可变类型
整型
浮点型
字符串
元组