Frage

I'm trying to use the with..as contruct in Python to make writing "reversible computing" code easier. However, using @contextmanager on a class method seems to change the default initialization of future class instances. Python 2.6 and 3.1 have the same behavior. Here is a simple example exhibiting this behavior:

#!/usr/bin/env python

import contextlib

class SymList:
    def __init__(self, L=[]):
        self.L = L

    @contextlib.contextmanager
    def SymAdd(self, a):
        self.L.append(a)
        yield
        self.L.append(a)

SL = SymList()
with SL.SymAdd(3):
    SL.L.append(5)
print(SL.L) # Expect and see [3, 5, 3]
SL2 = SymList()
print(SL2.L) # Expect [] and see [3, 5, 3]


  • Why isn't SL2 a fresh instance of SymList?
  • How is the SL2.L data member referring to the SL.L data member?
War es hilfreich?

Lösung

This behavior is due to how mutable default arguments work in Python.

Try changing SymList.__init__() to the following:

    def __init__(self, L=None):
        if L is None:
             self.L = []
        else:
             self.L = L

As you modify self.L in one instance you are also modifying the L that is passed into SymList.__init__(), so the result with your code is that all instances would share the same L attribute when the instance is first initialized.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top