一、函数返回值拆包
如果一个函数通过return返回了一个元组、列表、集合,可以通过拆包的方式将返回值进行拆分到每个变量中,这就是返回值拆包
通过函数返回值拆包,可以快速的将具体的数据用变量进行存储,这样对数据的处理会更加方便
def funch(a1,a2,a3):
a1=a3+a2
a2=a1+a3
a3=a1+a2
return[ a1,a2,a3 ]
a,b,c=funch(1,2,3)
print(a)
print(b)
print(c)
拆包时要注意,需要拆的数据的个数要与变量的个数相同,否则程序会异常
二、使用*拆包
有时在调用函数时,这个函数需要的是多个参数,而自己拥有的是一个列表或者集合这样的数据,此时就用可以用*拆包
def test(a,b,c):
print(a+b+c)
nums= (11,22,33)
test(*nums)
nums= [11,22,33]
test(*nums)
nums = {11, 22, 33}
test(*nums)
注意 *对列表、元组、集合可以拆包
三、使用**拆包
使用**可以对字典进行拆包,拆包的结果是命名参数,使用*拆包得到的是字典的键值
def test(age,name,qq):
print(name)
print(age)
print(qq)
nums = {
"name":"wang",
"age":18,
"qq":563940
}
test(**nums)
值得注意的是定义的函数参数要和键值相同,和左右顺序无关。可以理解为传入了一个命名参数。
不定长产生也含有 *args、**kwargs与此无关系。
四、引用
引用:就是地址
那地址是什么呢?可以理解为存放数据的空间在内存中的编号
获取地址函数:id(变量)
nums = {
"name":"wang",
"age":18,
"qq":563940
}
b= nums
print(id(nums))
print(id(b))
>>>
2284839482816
2284839482816
此时变量nums 、b存储的引用(地址)都是相同的,Python中的变量并不是真正存储数据,而是存储的数据所在内存中的地址,我们一般称之为引用
nums = {
"name":"wang",
"age":18,
"qq":563940
}
b= nums
print(id(nums))
print(id(b))
nums["hh"]="123"
print(nums)
print(b)
>>>
2225198970304
2225198970304
{'name': 'wang', 'age': 18, 'qq': 563940, 'hh': '123'}
{'name': 'wang', 'age': 18, 'qq': 563940, 'hh': '123'}
通过上面这个程序发现b指向的不是新的地址还是和nums地址一样,可以理解为他们共用同一个地址
a = [1, 2]
b = a
b.append(3)
print(id(a))
print(id(b))
b = [100, 200, 300]#b指向了新的数据地址
print(b)
print(a)
print(id(a))
print(id(b))
>>>
2142204601600
2142204601600
[100, 200, 300]
[1, 2, 3]
2142204601600
2142204554752
通过上面这个程序发现b指向的是新的地址。
之前为了更好的理解变量,把a=100理解为变量a中存放了100,事实上变量a存储是100的引用
五、引用当做实参
Python中调用函数时,传递实参实际上都是是引用,即传递的都是地址
只要是传递的引用,那么也就是说在函数中是可以直接对指向的数据进行修改
def test(p):
# 此时变量p也指向nums指向的列表
p.append(44)
print("在函数test中,p=", p)
nums = [11, 22, 33]
print("调用test函数之前,nums=", nums)
test(nums) # 此时将列表的引用当做了实参进行传递
print("调用test函数之前,nums=", nums)
>>>
调用test函数之前,nums= [11, 22, 33]
在函数test中,p= [11, 22, 33, 44]
调用test函数之前,nums= [11, 22, 33, 44]
注意:只要有右边不属于运算或者重新赋值,那么左边的变量就不会指向新的引用(地址)。
六 函数名也是引用
在Python中即使是函数名也是一个变量名,只不过这个变量没有指向普通的数据,而是指向了一段代码;也就是说如果定义了一个函数名字叫做test1就好比是一个变量名test1指向了那个代码块而已
def test1():
print("test1")
def test2():
print("test2")
test1()
test2()
test1=test2
test1()
test2()
>>>
test1
test2
test2
test2
所以当上述代码第11行test1 = test2时,就相当于让test1变量不在指向原本的代码块,而是指向新的代码块即test2指向的代码块
当我们用函数名()是实际上就是让指向的这块代码开始执行,当我们只用函数名时其实就是这个函数的引用
使用def定义的函数名,实际就是个变量名它存储了函数的引用
如果将另外一个变量,例如b保存了函数的引用,即也指向了同一个函数,那么b()就是调用函数