重複の可能性:
Python の「最小の驚き」: 変更可能な既定の引数
いくつかの単体テスト (python 2.7) を実行しようとしているときに、変数のスコープに関連する奇妙な動作が見られます。
インスタンス変数として単一のリストを持つ「ダミー」と呼ばれるクラスを含むモジュールがあります。このモジュールの単体テストでは、それぞれ独自のダミー インスタンスを作成する 2 つの個別のテスト ケースがあります。それにもかかわらず、2 番目に実行されるテストの Dummy インスタンスには、最初のテストで作成されたリストが含まれているようです。コードは次のとおりです。
mymodule.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
追加の詳細:
print mylist
ダミーのinitメソッドの最初の行としてa を配置すると、確かに、2 回目のテスト実行で、mylist=[1] が引数として渡されたかのように [1] が出力されます。明示的に指定する
dd = Dummy(mylist=[])
と、問題はなくなります。デフォルトの引数値と関係があるようですが、いずれにせよ、なぜそれが別のスコープに波及する必要があるのか はわかりません。