文章目录
- 函数二
- 变量作用域
- 局部变量
- 全局变量
- 多函数程序执行流程
- 返回值作为参数传递
- 函数的返回值
- 函数的参数
- 位置参数
- 关键字参数
- 缺省参数
- 不定长参数
- 拆包和交换两个变量的值
- 拆包
- 交换变量值
- 引用
- 了解引用
- 引用当作实参
- 可变和不可变型
函数二
变量作用域
变量作用域是变量生效的范围,主要分为两类:局部变量和全局变量。
局部变量
所谓局部变量是定义在函数体内部的变量,即只在函数体内部生效。
# 定义函数
def test1():
a = print
print(a)
# 执行函数
test1() # 100
print(a) # 报错,a没有被定义
变量a是定义在
testA
函数内部的变量,在函数外部访问则立即报错。
局部变量的作用;在函数体内部,临时保存数据,即当函数调用完成后,则销毁局部变量。
全局变量
所谓全局变量,指的是在函数体内、外都能生效的变量。
思考:如果有一个数据,在函数A和函数B都要使用,该怎么办?
答:将这个数据存储在一个全局变量中。
# 定义全局变量
a = 'www.'
b = '.com'
# 定义函数
def baidu():
x = 'baidu'
wangzhi = a + x + b
return wangzhi
def youxi():
b = '.cn'
x = '4399'
wangzhi = a + x + b
return wangzhi
# 验证
# print(wanghzi) # 报错没有被定义
bd = baidu()
print(bd) # www.baidu.com
yx = youxi()
print(yx) # www.4399.cn
print(b) # .com
思考:在youxi
函数内部的b = ‘.cn’
中的b是在修改全局变量的b吗?
答:不是。
自测:用Debug工具查看各个参数的赋值情况。
修改全局变量
global 函数
# 定义全局变量
a = 'www.'
b = '.com'
# 定义函数
def baidu():
x = 'baidu'
wangzhi = a + x + b
return wangzhi
def youxi():
global b
b = '.cn'
x = '4399'
wangzhi = a + x + b
return wangzhi
# 验证
# print(wanghzi) # 报错没有被定义
bd = baidu()
print(bd) # www.baidu.com
yx = youxi()
print(yx) # www.4399.com
print(b) # .cn
多函数程序执行流程
共用全局变量
# 定义全局变量
num = 1
def test1():
global num
# 修改全局变脸
num = 100
def test2():
# 调用test1函数中修改后的全局变量
print(num)
# 先调用test2,查看当前全局变量的值
test2() # 1
# 调用test1函数,执行函数内部代码:声明和修改全局变量
test1()
# 调用test2函数
test2() # 100
返回值作为参数传递
def test1():
return 50
def test2(num):
print(num)
# 1. 保存函数test1的返回值
result = test1()
# 2. 将函数返回值所在变量作为参数传递到test2函数
test2(result) # 50
函数的返回值
思考:如果应该函数如有些return,程序如何执行?
def re_num():
return 1
return 2
result = re_num()
print(result) # 1
答:只执行了一个return,原因是因为return可以退出当前函数,导致return下方的代码不执行。
思考:如果应该函数要有很多个返回值,该如何书写代码?
def re_num():
return 1,2
result = re_num()
print(result) # (1,2)
注意
return a,b
写法,返回多个数据的时候,默认是元祖类型。- return后面可以连接列表、元祖或字典,以返回过个值。
函数的参数
位置参数
调用函数时,根据函数定义的参数位置来传递参数
def user(name,age,gender):
print(f'名字是{name},年龄是{age},性别是{gender}')
user('溏心蛋','18','男') # 名字是溏心蛋,年龄是18,性别是男
传递和定义时位置要一致。
关键字参数
函数调用时,通过“键=值”形式加以指定。可以让函数更加清晰、容易使用,同时也清楚了参数的顺序需求。
def user(name,age,gender):
print(f'名字是{name},年龄是{age},性别是{gender}')
# user('溏心蛋','18','男') # 名字是溏心蛋,年龄是18,性别是男
user('溏心蛋',age=18,gender='男') # 名字是溏心蛋,年龄是18,性别是男
user('溏心蛋',gender='男',age=18) # 名字是溏心蛋,年龄是18,性别是男
注意:函数调用时,如果有位置参数时,位置参数必须写在关键字参数前面,但关键字参数之间不存在先后顺序。
缺省参数
缺省参数页脚默认参数,用于定义函数。为参数提供默认值,调用函数时可不传该默认参数的值(注意:所有位置参数必须出现在默认参数前,包括函数定义和调用)
def user(name,age,gender='男'):
print(f'名字是{name},年龄是{age},性别是{gender}')
user('溏心蛋',age=18) # 名字是溏心蛋,年龄是20,性别是男
user('小羊',age=18,gender='女') # 名字是小羊,年龄是18,性别是女
注意:函数调用时,如果为缺省参数值则修改默认值;否则使用这个默认值。
不定长参数
不定长参数也叫可变参数。用于不确定调用的时候会传递多少个参数(不传参也可以)的场景。此时,可用包裹(packing)位置参数,或者包裹关键字参数,来进行传参,会显得非常方便。
- 包裹位置传递
def user(*args):
print(args)
user('溏心蛋') # ('溏心蛋',)
user('溏心蛋',18) # ('溏心蛋', 18)
注意:传进的所有参数都会被args变量收集,它会根据传进参数的位置合并为一个元祖,args是元祖类型,这就是包裹位置传递。
- 包裹关键字传递
def user(**kwargs):
print(kwargs)
user() # {}
user( name='溏心蛋', age=18, id=520) # {'name': '溏心蛋', 'age': 18, 'id': 520}
综上:无论是包裹位置传递还是包裹关键字传递,都是一个组包的过程。
拆包和交换两个变量的值
拆包
- 拆包:元组
def t1():
return 100,200 # 返回一个元组
num1,num2 = t1()
print(num1) # 100
print(num2) # 200
- 拆包:字典
d1 = {'name':'溏心蛋','age':18}
a ,b = d1
# 对字典进行拆包,取出来的是字典的key
print(a) # name
print(b) # age
print(d1[a]) # 溏心蛋
print(d1[b]) # 18
交换变量值
需求:有变量a = 10
和b = 20
,交换两个变量的值。
方法一
借助第三变量储存数据
a = 10
b = 20
c = a
a = b
b = c
print(f'a = {a},b = {b}')
# a = 20,b = 10
方法二
a , b = 1 , 2
a , b = b , a
print(f'a = {a},b = {b}') # a = 2,b = 1
引用
了解引用
在Python中,值是靠引用来传递的。
我们可以用id()
来判断两个变量是否为同一个值的引用。
我们可以理解为id值为那块内存的地址标识。
# 1. int类型
a = 1
b = a
print(b) # 1
print(id(a)) # 2496481263856
print(id(b)) # 2496481263856
a = 2
print(b) # 1,说明int类型为不可变类型
print(id(a)) # 2799518023952
print(id(b)) # 2799518023920
# 2. 列表
aa = [10,20]
bb = aa
print(id(aa)) # 2279091682816
print(id(bb)) # 2279091682816
aa.append(30)
print(bb) # [10, 20, 30],列表类型为可变类型
print(id(aa)) # 2279091682816
print(id(bb)) # 2279091682816
引用当作实参
def test1(a):
print(a)
print(id(a))
a += a
print(a)
print(id(a)) # 不同
b = 100
test1(b)
可变和不可变型
所谓可变类型与不可变类型是指:数据能够直接进行修改,如果能直接修改那么就是可变,否则是不可变。
可变类型:列表、字典、集合
不可变类型:整型、浮点型、字符串、元组