zoukankan      html  css  js  c++  java
  • *的使用,装包解包

    分为三个场景

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

    在函数中用*

    用在形参中【装包】

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

    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, 实参不能用两个星号去解包
    • 在变量名前加星号,将该变量名作为可变长度的变量名, 且只能在列表 或者元祖 中去给这种变量赋值, 会优先把正常变量赋值,剩下的给这种可变长度的变量名
    • 在列表、元祖、集合、字典 的 内部 ,可以 直接 对 可迭代对象 进行解包
  • 相关阅读:
    路由器只要能连接上,就能得到密码,
    jmeter上传文件搞了一天,才搞定,没高人帮忙效率就是低,赶紧记下来,以备后用
    1关0不关
    AJAX学习
    建表原则
    设计模式——代理模式
    jdk动态代理机制
    ArrayList源码分析
    Java集合类:HashMap (基于JDK1.8)
    SpringMVC的数据转换、格式化和数据校验
  • 原文地址:https://www.cnblogs.com/alantammm/p/15474423.html
Copyright © 2011-2022 走看看