*的使用,装包解包

分为三个场景

  • 用在函数中时
  • 用在变量名时
  • 直接作用在数据上时

在函数中用*

用在形参中【装包】

在函数的形参中,是将多个数据打包,一个星号 位置参数打包成 元祖, 两个星号 键值对 打包成字典

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, 实参不能用两个星号去解包
  • 在变量名前加星号,将该变量名作为可变长度的变量名, 且只能在列表 或者元祖 中去给这种变量赋值, 会优先把正常变量赋值,剩下的给这种可变长度的变量名
  • 在列表、元祖、集合、字典 的 内部 ,可以 直接 对 可迭代对象 进行解包
原文地址:https://www.cnblogs.com/alantammm/p/15474423.html