• 深入剖析python中函数的参数类型及引用


    前面文章中,在定义爬虫函数时重点研究了*args、**kwargs两个参数的使用方法。

    https://www.cnblogs.com/chen117/p/12952601.html

    但在后面的学习中发现,当时对函数的理解还比较粗浅,经过更深入的学习——主要还是看了下面这篇知乎的狠贴,颠覆了之前了解的分类方式,所以专门写这篇总结一下。

    https://www.zhihu.com/question/57726430

    (当前最新的python版本是 3.8.3)

    函数参数的作用是传递数据给函数使用。

    一、参数有两种形式:形参、实参。

    【实参】

    调用函数时的参数,格式:

    https://www.cnblogs.com/chen117/p/12952601.html

    funcname(实参表)

    实参表由左到右就是简单的两个部分:

    funcname(位置实参, 关键字实参) 

    注意:这两种实参前后顺序是严格的,两个部分都可以缺省,但不能相互交错。(这确定了位置匹配的唯一性)

    “关键字实参”可以摆脱位置约束。两种实际参数要共同覆盖所有没有默认值的形式参数。

    例1:(关键字实参形式可以摆脱位置约束)

     

     

    【形参】

    定义函数时的参数。

    # 函数定义,独立成块的代码,圆括号内是形式参数

    def funcname(形参表):
        函数体

     

     

    形参从左到右可以分为五个部分:

    def funcname(【限定位置形参】,普通形参】,特殊形参args,限定关键字形参】,特殊形参kwargs):

        pass

    其中两个特殊形参分别只能是0个或1个,其他形参可以是0个或多个。

    尽管函数定义的形式如此丰富,但调用形式永远是简单的两部分——位置实参+关键字实参,与有无默认值无关。

    二、形参类型:

    1、限定位置形参:

    纯位置形参。是为了限制开头几个参数只能按位置传递。(不能使用关键字实参形式)

    Python从3.7开始,为某些内置函数定义了positional-only的形参。从Python 3.8开始,positional-only形参将可正式用于自定义函数中,它们必须放在形参表的最前面,并在后面使用斜杠/(独占一个参数位)与普通形参分隔。

    例2.1:(a,b,c为限定位置形参,不能按关键字传递)

    2、普通形参:

    按最简形式定义出来的就是【普通形参】,它们是“位置、关键字兼容”的。

    例2.2:( d为普通形参,可以按位置传递,也可以按关键字传递)

      

    3、限定关键字形参(命名关键字参数)

    keyword-only限制后面几个参数只能按关键字传递,这往往是因为后面几个形参名具有十分明显的含义,显式写出有利于可读性;或者后面几个形参随着版本更迭很可能发生变化,强制关键字形式有利于保证跨版本兼容性。

    必须传入参数名,可以有缺省值。

    例3.1:(d为限定关键字参数,只能按关键字传递)

     

     

    例3.2:(当限定关键字参数d有缺省值时,可以省略)

     

     

    4、特殊形参:*args

    是一种可变参数,也叫元组参数。可以是元组也可以是列表序列。这种形式表示接受任意多个实际参数将其放到一个元组tuple中。

    它位于普通形参之后,又只能接受位置实参。

    例4:(虽然叫元组参数,但不要传入一个元组对象进去,需要 * 解封。)

     

    5、特殊形参:**kwargs

    也是一种可变参数,也叫关键字参数、字典参数,这种形式表示接受任意多个实际参数将其放到一个字典dict中。

    关键字参数是一个由键值对组成的集合,允许通过变量名进行匹配,而不是位置。

    例5:(虽然叫字典参数,但不能传入一个完整的字典对象,需要**解封)

     

    6、混合参数

    *args接收多余的位置实参,**kwargs接收多余的关键字实参。

    *args 和 **kwargs 并不是 python 中的参数关键字,而是一种惯用写法。

    例6.1:

     

    例6.2:命名关键字参数不能与可变参数 *args 组合,可以与 **kwargs 组合。

     

    四、特殊传参方法:

    1、序列解包:

    当你有个序列对象,想将其中元素解放出来作为调用函数的位置实参时,给它加个前缀*即可。

    例7:

    2、字典解包:

    当你有个字典对象,且其中的键都是合法的形参名时,想把其中的键值对解放出来作为调用函数的关键字参数,给它加个前缀**即可。

    例8:

     

     

     五、参数传递基本法则:

    将实际参数传递给形参的方式有两种:

    值传递:实参为不可变对象,传递给形参后,形参的值改变,实参值不变。

    引用传递:实参为可变对象,传递给形参后,形参的值改变,实参值改变。(传递地址)

    当函数被调用时,解释器会查看传入的变量(内存地址)指向的类型,如果是可变类型的值,就按照引用传递变量;如果是一个非可变类型的值,就按照值传递变量。

    尽管函数定义的形式如此丰富,但调用形式永远是简单的两部分——位置实参+关键字实参。注意这两个前后顺序是严格的,两个部分都可以缺省。

    与有无默认值无关,位置实参永远按位置传递给*或*args之前对应的形参(即限定位置形参和普通形参),多余的位置实参传入*args(如果有的话);

    关键字实参则匹配剩下的普通形参和限定关键字形参(非限定位置形参),多余的关键字实参则传入**kwargs(如果存在的话)。

  • 相关阅读:
    CodeForces
    [VS Code] 入门-自定键盘快捷键
    代码格式化工具:clang-format
    用 shell 脚本做 restful api 接口监控
    [apue] 一图读懂 unix 文件句柄及文件共享过程
    Python Django开发的WebSSH 堡垒机
    最好用的流程编辑器bpmn-js系列之基本使用
    树莓派系列(第三篇):树莓派换源 、连接WiFi、安装transmission、samba
    教你用MacBook玩童年FC游戏
    vscode、hbuider编辑器代码片段示例
  • 原文地址:https://www.cnblogs.com/chen117/p/12982810.html
Copyright © 2020-2023  润新知