分为三个场景
- 用在函数中时
- 用在变量名时
- 直接作用在数据上时
在函数中用*
用在形参中【装包】
在函数的形参中,是将多个数据打包,一个星号 位置参数打包成 元祖, 两个星号 键值对 打包成字典
def fun(a,*args,**kwargs):
print(a)
print(args)
print(kwargs)
fun(1,2,3,name='paul')
"""
输出:
1
(2,3)
{"name":"paul"}
"""
用在函数实参中【解包】
**在函数的实参中,星号是解包操作, 将 可迭代对象 解包成多个实参 ,其中实参用一个星号解包 字典时,只会返回key
def f2(a,*args):
print(a)
print(args)
f2(*'1234')
f2(*[1,2,3,4])
f2(*(1,2,3,4))
"""
三个都是输出:这里就是将实参的这个可迭代对象 解包成了 四个参数
1
(2,3,4)
"""
print(*'abc') # 输出 a b c 直接作为print函数的实参,解包出来三个字符串
print(*range(5)) #输出 0 1 2 3 4
# 实参是字典的时候
def f3(a):
print(*a)
f3({'name': 123, 'kk': 333}) # 输出 name kk
# 当需要解包成键值对的时候
def f2(name,kk):
print('pass')
def f(kwargs):
f2(**kwargs)
f({'name': 123, 'kk': 333}) #输出pass
"""
将字典解包成完全的键值对,一般只会在如上这种情况下使用,必须保证调用解包的函数的参数和解包出来的键值对的key能对应的上
典型例子: django restframework中 反序列化 create()方法
def create(self,validated_data):
#需要将is_valid()验证后的 validated_data 字典解包成键值对 供orm使用
return Person.objects.create(**validated_data)
"""
在变量名中使用*
在变量名前加星号,将该变量名作为可变长度的变量名, 且只能在列表 或者元祖 中去声明这种变量, 会优先把正常变量赋值,剩下的给这种可变长度的变量名
当我们想要对一个可迭代对象进行拆分,并赋值给相应的变量时,我们可以用星号标记某个变量,这个变量表示可变变量,意思表示其内容是不定的,内容根据其他的变量的个数决定。因为其原理就是优先赋值给其他确定的变量,然后剩下的内容再赋值给可变变量,实际上,可变变量的内容就是对可迭代对象剩下内容解包后得到的内容,并以列表list对象返回给变量
>>> a,*b = 'xyz' # 变量名在元祖中
>>> a
'x'
>>> b
['y', 'z']
>>> [*a,b]='123' # 变量名在列表中
>>> a
['1', '2']
>>> {*a,b}='xyz'
SyntaxError: can't assign to literal # 报错 变量名只能在元祖 列表中声明
>>> a,*b = range(5)
>>> a
0
>>> b
[1, 2, 3, 4]
>>> a,*b = 123 #报错,必须是对可迭代对象的拆分
一个语句中不能出现两个可变变量
>>> *a,b,*c = 'dasdada' # 报错
SyntaxError: two starred expressions in assignment
当元素不够用的时候,先给确定长度的变量,*标识符 取剩下的
>>> *a,b,c = [1,2]
>>> a
[]
>>> a,b,c
([], 1, 2)
直接作用在数据上
在 列表、元祖、集合、字典 的内部, 将可迭代对象直接解包, 如果不是在这些容器里面操作,就会报错 比如 直接 *'abc' 会报错
>>> [*'123']
['1', '2', '3']
在元祖内部解包:
>>> *range(5), # 注意这里有个逗号,表示是个元祖 等同于 (*range(5),) range()返回的是一个可迭代对象 要是直接 *range(5)就会报错,因为不是在特定容器内解包
0, 1, 2, 3, 4)
在集合中解包
>>> {*'abc'}
{'a', 'b', 'c'}
在字典中解包
>>> {*{'name':'kobe'}}
{'name'} # 一个星号 解包出来的只有字典的key,相当于是在 一个集合里面 有一个元素 是一个字典,然后解包出来key 放在这个集合中
>>> {**{'name':'kobe'}}
{'name': 'kobe'} # 两个星号,就直接把整个字典解包出来
与变长变量名一起使用
>>> a,*b = [*'abcsd']
>>> a
'a'
>>> b
['b', 'c', 's', 'd']
总结
- 在函数的形参中,是将多个数据打包,一个星号 位置参数打包成 元祖, 两个星号 键值对 打包成字典
- 在函数的实参中,星号是解包操作, 将可迭代对象解包成多个实参 ,其中实参用一个星号解包 字典时,只会返回key, 实参不能用两个星号去解包
- 在变量名前加星号,将该变量名作为可变长度的变量名, 且只能在列表 或者元祖 中去给这种变量赋值, 会优先把正常变量赋值,剩下的给这种可变长度的变量名
- 在列表、元祖、集合、字典 的 内部 ,可以 直接 对 可迭代对象 进行解包