>>> 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