2012-08-07 4 views
3

파이썬에서 with..as contruct를 사용하여 "reversible computing"코드를 더 쉽게 작성하려고합니다. 그러나 클래스 메서드에 @contextmanager을 사용하면 향후 클래스 인스턴스의 기본 초기화가 변경되는 것 같습니다. 파이썬 2.6과 3.1도 같은 동작을합니다.Python : 클래스 메소드에서 contextmanager를 사용하여 예기치 않은 동작이 발생했습니다.

#!/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] 


  • SL2SymList의 새로운 인스턴스가 아닌 : 다음은 간단한 예제는이 동작을 전시한다?
  • SL2.L 데이터 멤버는 SL.L 데이터 멤버를 참조하여 어떻게됩니까?

답변

14

이 동작은 mutable default arguments이 어떻게 Python에서 작동하는지 때문입니다.

봅니다 다음에 SymList.__init__() 변경 : 당신은 또한 SymList.__init__()로 전달되는 L을 수정하는 하나 개의 인스턴스에 self.L을 수정, 그래서 당신의 코드로 결과가 모든 인스턴스가 공유 할 것입니다으로

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

인스턴스가 처음 초기화 될 때 동일한 L 속성

+0

그건 의미가 있습니다. 나는 그것이 장식 자와 더 좋아하는 무엇인가라고 생각하면서 눈이 멀었다. 감사! – user1582421

관련 문제