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

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

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

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

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

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

【实参】

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

funcname(实参表)

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

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

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

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

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

2007221-20200528224304312-1193588552.png

2007221-20200528224632234-901795665.png

【形参】

定义函数时的参数。

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

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为限定位置形参,不能按关键字传递)

2007221-20200528225243437-1656019245.png

2007221-20200528225215527-1191656407.png

2、普通形参:

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

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

2007221-20200528225348751-1653175426.png

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

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

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

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

2007221-20200528230509606-1524580339.png

2007221-20200528230522822-107849672.png

2007221-20200528230637279-1771930799.png

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

2007221-20200528230850410-909112549.png

2007221-20200528230927063-100799428.png

4、特殊形参:*args

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

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

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

2007221-20200529091220434-777628686.png

2007221-20200529091245892-781869941.png

5、特殊形参:**kwargs

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

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

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

2007221-20200528235422381-1946578593.png

2007221-20200528235441299-1438598752.png

6、混合参数

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

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

例6.1:

2007221-20200529000314971-421069301.png

2007221-20200529000425954-1012165853.png

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

2007221-20200529092258755-836015137.png

2007221-20200529000540933-1398755764.png

四、特殊传参方法:

1、序列解包:

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

例7:

2007221-20200529000649741-109104744.png

2007221-20200529000745225-1546207263.png

2、字典解包:

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

例8:

2007221-20200529000941659-382950964.png

2007221-20200529001006524-1083500017.png

五、参数传递基本法则:

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

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

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

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

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

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python 函数参数有两种传递方式:值传递(pass by value)和引用传递(pass by reference)。在大多数情况下,Python 实际上是通过引用传递参数的,因为 Python 是一种动态类型语言,变量名只是指向对象的引用。 **值传递(call-by-value):** 在其他一些语言(如 C/C++),如果函数接受的是基本数据类型(如 int、float 等),则是按值传递的。这意味着,当你在函数内部修改这样的参数,原始值不会改变,因为它创建了一个新的副本。在 Python ,对于不可变类型(如整数、浮点数、字符串等),行为类似值传递,因为它们是不可变的。 **引用传递(call-by-reference):** 然而,对于可变类型(如列表、字典、集合等),Python 实际上是按照引用传递的。当你把一个可变对象作为参数传入函数函数会接收这个对象的引用,而不是复制。因此,函数内部对对象的操作会影响到原始对象,因为你改变了引用所指向的内容。 例如: ```python def change_list(l): l.append(42) my_list = [1, 2, 3] change_list(my_list) print(my_list) # 输出: [1, 2, 3, 42] ``` 在这个例子,`change_list`函数改变了 `my_list` 的内容,因为它是通过引用传递的。 **相关问题--:** 1. Python 如何区分值传递和引用传递? 2. 对于不可变类型Python 是否也是按引用传递? 3. 在 Python ,如何避免意外地修改传入的可变对象?

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值