Python3 - 定义有默认参数的函数

2018-12-23  本文已影响46人  惑也

问题

定义一个函数或者方法,它的一个或多个参数是可选的并且有一个默认值。

解决方案

在函数定义中,直接给参数指定一个默认值,并放到参数列表最后就行了。例如:

def spam(a, b=42):
    return a, b

print(spam(1))
(1, 42)

print(spam(1, 2))
(1, 2)

如果默认参数是一个可修改的容器,比如一个列表、集合或者字典,可以使用None作为默认值,就像下面这样:

# Using a list as a default value
def spam(a, b=None):
    if b is None:
        b = []
    ...

讨论

默认参数的值,仅仅在函数定义的时候赋值一次。试着运行下面这个例子:

x = 100

def func(a, b=x):
    print(a, b)

print(func(1))
1 100

x = 1
print(func(1))
1 100

当改变x值时,对默认参数值并没有影响,这是因为在函数定义的时候就已经确定了它的默认值。

默认参数的值,通常应该是不可变的对象,比如None、True、False、数字或字符串。 特别的,尽量不要像下面这样写代码:

def spam(a, b=[]): # NO!
    ...

如果这么设置默认参数的值,当默认值在其他地方被修改后,会影响到下次调用这个函数时的默认值。比如:

def fun(a, b=[]):
    print(b)
    return b 

r = fun(1)
print(r)
[]
[]

r.append(99)
print(fun(1))
[99]
[99]

当需要测试函数的某个可选参数,是否被使用者传递进来时。尽量不要用某些默认值,比如None、 0或False,来测试使用者是否提供参数默认值,因为这些值都是合法的值,是可能被用户传递进来的。

为了解决这个问题,可以创建一个独一无二的私有对象实例,在函数里面,通过检查传递的参数值与这个自定义的实例是否一样来判断。示例:

_no_value = object()

def func_no_value(a, b=_no_value):
    if b is _no_value:
        return 'No b value supplied'
    else:
        return a, b

print(func_no_value(1))
No b value supplied

print(func_no_value(1, None))
(1, None)

这里使用 object() 看上去不太常见。object 是python中所有类的基类。 创建 object 类的实例,并没有什么实际用处,因为它并没有任何有用的方法,也没有任何实例数据,唯一能做的就是测试同一性,这个刚好符合“同一性测试”的需求。

上一篇下一篇

猜你喜欢

热点阅读