2

可能的重复:
Python 中的“Least Astonishment”:可变默认参数

在尝试运行一些单元测试(python 2.7)时,我看到了一些与变量范围相关的奇怪行为:

我有一个包含一个名为“Dummy”的类的模块,它有一个列表作为实例变量。在我对该模块的单元测试中,我有两个单独的测试用例,每个测试用例都创建自己单独的 Dummy 实例。然而,第二个运行的测试中的 Dummy 实例似乎包含在第一个测试中创建的列表。这是代码:

我的模块.py:

class Dummy(object):
    def __init__(self, mylist=[]):
        self.mylist = mylist

test_mymodule.py:

class TestDummy(unittest.TestCase):
    def testDummy1(self):
        d1 = Dummy()          # d1.mylist is empty, []
        d1.mylist.append(1)   # mylist = [1]
        self.assertEqual(d1.mylist, [1])

    def testDummy2(self):
        d2 = Dummy()          # d2.mylist = [1] !
        d2.mylist.append(2)   # d2.mylist = [1,2]
        self.assertEqual(d2.mylist, [2]) # FAILS

额外细节:

  1. 如果我将 aprint mylist作为 Dummy 的init方法的第一行,果然,在第二次测试运行时,它会打印 [1],就好像 mylist=[1] 作为参数传入一样

  2. 如果我明确指定dd = Dummy(mylist=[]),那么问题就会消失。它似乎与默认参数值有关,但我不清楚为什么无论如何它应该溢出到不同的范围。

4

1 回答 1

3

这与单元测试无关,而是与 Python 如何处理函数的默认参数有关。def执行语句时对函数默认参数求值一次。

这意味着您已经创建了一个列表,该列表用作默认参数,__init__并且只要该函数存在,该列表就会存在。

None使用(或其他标记值)作为默认值很容易避免:

class Dummy(object):
    def __init__(self, mylist=None):
        self.mylist = mylist if mylist is not None else []
于 2012-11-23T09:20:40.207 回答