从先前的函数调用保留的函数参数中的默认值

时间:2018-10-01 18:20:21

标签: python python-3.x

我注意到python中有一个奇怪的行为,有人可以告诉我这种行为的原因吗?

如果我调用没有属性的函数,则默认值为保留其状态。您可以查看以下示例以更好地了解

class EvenStream(object):
    def __init__(self):
        self.current = 0

    def get_next(self):
        to_return = self.current
        self.current += 2
        return to_return


class OddStream(object):
    def __init__(self):
        self.current = 1

    def get_next(self):
        to_return = self.current
        self.current += 2
        return to_return


def print_from_stream(n, stream=EvenStream()):
    for _ in range(n):
        print(stream.get_next())


print_from_stream(2)
print('*****')
print_from_stream(2)
print('*****')
print_from_stream(2, OddStream())
print('*****')
print_from_stream(2, OddStream())

输出: 我原本希望是0,2,0,2,但这给了我0,2,4,6

0
2
*****
4
6
*****
1
3
*****
1
3

1 个答案:

答案 0 :(得分:2)

发生了什么事?

当python看到

def print_from_stream(n, stream=EvenStream()):

它将EvenStream()评估为默认参数。这是一个明确的对象。每次您使用默认参数调用print_from_stream时,它都会使用与首次评估EvenStream()时创建的实例相同的实例。 print_from_stream现在具有关联的对象default_stream。永远不会使用新的EvenStream更新该对象。在C ++语言中,您已经创建了一个static变量。

修复

print_from_stream的默认参数设为None。然后,添加

if stream is None:
    stream = EvenStream()

功能顶部。每次您使用默认参数调用函数时,都会重新创建EvenStream()的实例。

请注意,它与以前略有不同,因为print_from_stream(10, None)现在可以工作并提供偶数,而不是崩溃。这仍然是Python的一种良好做法,类似于在JS函数中传递undefined就像没有提供任何参数一样。如果用户不想命名其参数,它可以使用户跳过第二个参数也可以跳到第三个参数。