zoukankan      html  css  js  c++  java
  • 参数打包,解包

    Python中的*号使用场景与区别

    直白点的区别就是:函数调用时,*和都是解包,函数定义时是将传过来的参数进行打包**

    星号的使用场景有两个

    1. 在【函数定义】和【函数调用】的时候使用
    2. 作为接收序列参数:a,*b=1,2,3,4

    这里主要讲第一种


    函数定义时.

    • args: 接收传递过来的序列引用,读取引用中的位置参数,【打包】成一个元祖,将引用指向args
    • kwargs: 接收传递过来的字典引用,读取引用中的关键字参数,【打包】成一个字典,将引用指向kwargs

    注意:如果参数列表有*args,**kwargs,但是没有接收到参数,那么输出args就是一个空元祖,kwargs是个空字典,当参数args只有一个时,那么输出的元祖就是(1,)后面有一个,代表是个元祖

    函数调用时

    • *args  和**kwargs:传递的是序列的引用,获取引用中的值,然后作为实参传递
    • 注意事项:由于是引用,会更改内部的值,如图

    场景1:函数定义与调用都不使用*号

    a=[1,2,3,4]
    b=(7,8,9,10)
    c={'age':18,'name':'vdx'}
    
    def f(tmp):
        print(tmp)
        print(*tmp)  # 这里面和上面一样序列解包
    f(a)  # 直接传列表引用作为参数
    f(b) # 与函数外面保持一致
    f(c) # 与函数外面保持一致
    
    [1, 2, 3, 4]
    1 2 3 4
    (7, 8, 9, 10)
    7 8 9 10
    {'age': 18, 'name': 'vdx'}
    age name
    

    提问:既然能直接定义一个变量接收序列的引用,为什么还需要用*和**?

    思考:虽然效果是一样的,但是有些情况不是直接传列表,而是单个单个的位置参数传递,比如fun(1,2,3)


    场景2:函数定义时:使用*号

    a=[1,2,3,4]
    b=(7,8,9,10)
    c={'age':18,'name':'vdx'}
    
    def f(*tmp):
        print(tmp)
        print(*tmp)  
    f(a)  # 直接传列表引用作为参数,注意:函数能直接更改原件,如果想弄副本,加上*
    f(b) 
    f(c)
    
    (1, 2, 3, 4)
    1 2 3 4
    ((7, 8, 9, 10),)
    (7, 8, 9, 10)
    ({'age': 18, 'name': 'vdx'},)
    {'age': 18, 'name': 'vdx'}
    

    场景3:函数定义时:使用*号

    a=[1,2,3,4]
    b=(7,8,9,10)
    c={'age':18,'name':'vdx'}
    
    def f(**tmp):
        print(tmp)
    f(**c) # 与函数外面保持一致
    
    {'age': 18, 'name': 'vdx'}
    

    提示:对字典使用*,能够取出里面的key


    为什么我们不能print(**kwargs),却能print(*args)

    不是说**不能解包,而是print不支持输出关键字参数

    区别归纳

    1.之前赋值时,*可以用来接收多余的对象值,那种用法与函数中的用法不一样,切记混合使用,【一个是赋值时接收多余的参数,一个是在函数中传递,接收多个值是使用】

    例题:

    # 二、请写出下列代码的运行结果
    def f(str1, *args, **kwargs):
        print(str1, args, kwargs)
    
    
    l = [1, 2, 3]
    t = [4, 5, 6]
    d = {"a": 7, "b": 8, "c": 9}
    f(1, 2)
    f(1, 2, 3, "python")
    f("python", a=1, b=2, c=3)
    f("python", l, d)
    f("python", *t)
    f('python', *l, **d)
    f("python", q="winning", **d)
    print('-' * 90)
    
  • 相关阅读:
    Spring 依赖注入控制反转实现,及编码解析(自制容器)
    Bean的作用域及生命周期
    spring三种实例化bean的方式
    编码剖析Spring管理bean的原理
    Spring基本概念
    hibernate 一对一关联关系 及其懒加载,总结
    hibernate中 inverse的用法(转载)
    SpringMVC_RESTRUL_CRUD
    java 位移运算符
    三目运算中的类型转换
  • 原文地址:https://www.cnblogs.com/zhongzhouyun/p/14967585.html
Copyright © 2011-2022 走看看