本文已参与「新人创作礼」活动,一起开启掘金创作之路。
函数提高
目标
- 变量的作用域
- 多函数程序执行流程
- 函数的返回值
- 函数的参数
- 拆包和交换两个变量的值
- 引用
- 可变和不可变类型
变量的作用域
什么是变量的作用域
其实变量的作用域就是变量生效的范围
变量的作用域中有局部变量和全局变量
局部变量
所谓的局部变量是定义在函数内部的变量,既在函数内部生效
def testA():
a=100
print(a)
#这里调用了testA函数,就会去再执行函数里面的代码,
testA()
#如果我们直接调用变量a
#print(a)
#这样直接调用变量a是不可以的,
#因为我们的变量a是内部的是testA这个函数内部的,比赛全局变量
全局变量
所谓的全局变量,指的就是函数体内,外部能生效的变量
能外部调用的
#定义一个全局变量
a=100
#定义一个函数
def testA():
#函数执行代码是打印变量a
print(a)
#调用函数testA(),
testA()
#打印变量a
print(a)
#两个都可以正确的打印出100
#原因是我们的变量a是全局变量
打印结果
100
100
修改局部变量
先看代码
a=100
def c():
print(a)
def b():
a=200
print(a)
c()
b()
输出是
100
200
为什么会这样呢
首先我们来查看一下
a=100是全局变量
a=200是我们b()函数内的局部变量
当函数中有局部变量的时候而外部又有全局变量的时候,优先调用局部变量
实现局部变量外部调用
a=100
def c():
print(a)
def b():
global d
d=200
print(d)
c()
b()
print(d)
global是一个声明,被他声明的变量就拥有了全局变量的能力
所以当我们外部调用打印d=200的时候是可以的
输出的结果为
100
200
200
多函数程序执行流程
一般情况下,一个程序往往由多个函数组成,并且这多个函数共同共享某些数据
差不多下面
a=100
def c():
print(a)
def b():
global d
d=200
print(d)
c()
b()
print(d)
函数的返回值
def a():
#返回值为50
return 50
def b(num):
#这里num是空的意思表示都可以
print(num)
#这里,设置一个变量d,变量d对应赋值是a()
d=a()
#这里调用b函数,函数中参数写d,就是调用变量d,前提是b函数参数位置是num
b(d)
函数的参数
位置参数
位置参数:调用函数时根据函数定义的参数位置来传递参数
a=input("姓名:")
b=input("年龄:")
c=input("性别:")
def user(name,age,gender):
print(f'你的名字是:{name},年龄是:{age},性别是:{gender}')
user(a,b,c)
位置参数的话,很好理解,一个参数代表一个位置,name他代表的获取名称的位置,用户输入的名称都会传输到name这个位置上
关键字参数
函数调用,通过键值形式加以指定。可以让函数更加清晰,容易使用,同时也清除了参数产生的顺序需求
def a(name,age,gender):
print(f'你的名称是:{name},你的年龄是:{age},你的性别是:{gender}')
a('大帅哥',age=18,gender='男')
a(name='大帅哥1',age=18,gender='男')
a(name='大帅哥1',gender='男',age='18')
输出
你的名称是:大帅哥,你的年龄是:18,你的性别是:男
你的名称是:大帅哥1,你的年龄是:18,你的性别是:男
你的名称是:大帅哥1,你的年龄是:18,你的性别是:男
注意:位置参数必须在关键字参数的前面,但是关键字参数之间不存在先后顺序
缺省参数
缺省参数也叫默认参数,用于定义函数,为参数提高默认值,调用函数时可不传该默认参数值,
def a(name,age,gender='男'):
print(f'您的名称是:{name},年龄是:{age},性别是:{gender}')
a('大帅哥',20,'女')
输出
您的名称是:大帅哥,年龄是:20,性别是:女
注意:函数调用时,如果为缺省参数传值修改默认参数值,否则使用这个默认值
不定长参数
不定长参数也叫可变参数。用于不确定调用的时候会传递多少个参数(不参数也可以)的场景。此时,可以包裹(packing)位置参数,或者包裹关键字参数,来进行参数传递,会显得方便
def a(*user):
print(user)
a('TOM')
a('TOM',18)
输出
('TOM',)
('TOM', 18)
拆包和交换两个变量的值
拆包
拆包:元组
def a():
return 100,200
a,b=a()
print(a)
print(b)
输出
100
200
拆包:字典
def a(*aa, **aaa):
print(aa)
print(aaa)
b = (1, 2, 3)
c = {"name": "小明", "age": 18}
a(b, c)
输出
((1, 2, 3), {'name': '小明', 'age': 18})
{}
交换变量值
交换变量值是什么呢
首先我们有两个变量
一个是变量a另外一个是变量b
a=10
b=20
我们这两个变量已经是定义好了,交换变量值,就是把a和b两个变量的值进行交换
这时a=20,b=10
注意在交换的时候需要用到第三个变量
方法一
a=10
b=20
c=0
c=a
a=b
b=c
print(a)
print(b)
输出
20
10
方法二
a,b=1,2
a,b=b,a
print(a)
print(b)
输出
2
1
引用
了解引用
在python中,值(数据)是靠引用来传递来的
在数据和值的传递过程中都需要用到变量来做为帮助
字符串
#1.字符串引用
a='1234'
b=a
a='hello'
print('a:',a) #a:hello
print('b:',b) #b:1234
#查看内存地址
print('a的内存地址是:',id(a))
print('a的内存地址是:',id(b))
结果是:
a: hello b: 1234 a的内存地址是: 1651738050720 a的内存地址是: 1651737219456
分析:b的值指向a的值。python开辟了新的内存空间给b,所以a和b的内存地址不一样。
浮点型
#2.浮点型引用
x=3.14
y=x
x=9.88
print('x:',x)
print('y:',y)
print('x的内存地址是:',id(x))
print('y的内存地址是:',id(y))
结果是:
x: 9.88 y: 3.14 x的内存地址是: 2578075558248 y的内存地址是: 2578075558008
指向值的地址依然不同。
整型就略去了。
元祖
元祖虽然是序列,且包含多个元素,但是不支持原处修改,如tuple[1]=1是非法的。
#3.元祖引用
t1=(1,2,3,4,5)
t2=t1
t1=('tuple','hello')
print('t1:',t1)
print('t2:',t2)
print('t1的内存地址是:',id(t1))
print('t2的内存地址是:',id(t2))
结果是:
t1: ('tuple', 'hello') t2: (1, 2, 3, 4, 5) t1的内存地址是: 1599025348360 t2的内存地址是: 1599023460776
但是元祖虽然是不可变数据类型,但是有一点必须注意就是元祖中的每个元素都不可变,才可以,如下例子:
# 元祖不可变
t=(1,2,3,['A','a','B','b'])
t[3][0]='x'
t[3][2]='D'
print('t修改后为:',t)
结果是:
t修改后为: (1, 2, 3, ['x', 'a', 'D', 'b'])
分析:因为元祖中的第4个元素是列表,列表本身是可变数据类型。元祖所谓的不变,是内容的地址指向不变, 上面的这个例子中第四个元素又指向了列表,列表是可变的。所以,要创建一个内容不可变的元祖,必须保证元祖的每个元素不可变。
可变和不可变类型
所谓的可变类型和不可变类型指的是数据能够直接进行修改,如果能直接修改那么就是可变,否则是不可变
可变类型
列表
字典
集合
不可变类型
整型
浮点型
字符串
元组
总结
变量作用域
局部:函数体内部能生效
全局:函数体外能生效
函数返回值写法:
retuen 表达式1,表达式2
函数的参数
位置参数
形参和实参的个数和书写顺序必须一致
关键字参数
写法:key=value
特点:形参和实参的书写顺序不一致,关键字·参数必须书写在位置参数后面
缺省参数
缺省参数就是默认参数
写法:key=vlaue
不定长位置参数
收集所有位置参数,返回一个元组
不定长键字参数
收集所有关键字参数,返回一个元组
引用
python中,数据的传递都是通过引用的
\