>>> from env_helper import info; info()
页面更新时间: 2023-12-27 09:27:23
运行环境:
Linux发行版本: Debian GNU/Linux 12 (bookworm)
操作系统内核: Linux-6.1.0-16-amd64-x86_64-with-glibc2.36
Python版本: 3.11.2
3.14. 警惕默认参数潜在的问题¶
默认参数可以给函数的使用带來很大的灵活性,当函数调用没有指定与形参对应的实参 时就会自动使用默认参数。
>>> def appendtest (newitem, lista =[]):# 默认参數为空列表
>>> print (id(lista))
>>> lista.append (newitem)
>>> print (id(lista))
>>> return lista
>>> appendtest("a", ['b',2, 4, [1,2]])
139637852362248
139637852362248
['b', 2, 4, [1, 2], 'a']
现在请读者思考这么一个问题:如果第二个参数采取默认参数,连续调用两次
appendtest(1),
appendtest(‘a’),函数的返回值是多少?期望的结果应该是[1]
和['a']
,对吧?
可是实际情况却输出了 [1]
和[1,'a']
那么这是什么原因呢?
def
在Python中是一个可执行的语句,当解释器执行def
的时候,默认参数也会被计算,
并存在函数的.func_defaults
属性中由于Python中闲数参数传递的是对象,可变对象在调
用者和被调用者之间共享,因此当首次调用appendtest(1)的时候,[]
变为[1]
,而再次调用的
时候由于默认参数不会重新计算,在[1]
的基础上便变为了[1,'a']
。我们可以通过査看函数的
ftinc_defaults来确认这一点。
>>> appendtest(1)
139637852362184
139637852362184
[1]
appendtest (’ a ’)
39022960 39022960 [1, ra’]
appendtest. func_defaults
([1, ra’]r)
appendtest. fimc_def aults [Of I:】=[] appendtest. func_defaults
([],)
如果不想让默认参数所指向的对象在所有的函数调用中被共享.而是在函数调用的过程 中动态生成,可以在定义的时候使用None对象作为占位符。因此本节幵头的例子应该修正 为如下形式:
>>> def appendtest (newitem, lista=None) : # R认参数改为 None ...
>>> if lista is None:
>>> lista = []
>>> lista.append (newitem)
>>> return lista
最后以一个问题结束本节:假设reportO函数需要传人当前系统的时间并做一些处理, 下面两种参数传递方式哪神正确呢?读者应该知道答案了!
>>> import time
>>> def report(when = time.time()):
>>> pass
>>> def report (when = time.time()):
>>> pass