2010-05-21 4 views
8

코드 :Python 기본 클래스는 속성을 공유합니까? test.py에서

class Base(object): 
    def __init__(self, l=[]): 
     self.l = l 

    def add(self, num): 
     self.l.append(num) 

    def remove(self, num): 
     self.l.remove(num) 

class Derived(Base): 
    def __init__(self, l=[]): 
     super(Derived, self).__init__(l) 

파이썬 쉘 세션 :

Python 2.6.5 (r265:79063, Apr 1 2010, 05:22:20) 
[GCC 4.4.3 20100316 (prerelease)] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import test 
>>> a = test.Derived() 
>>> b = test.Derived() 
>>> a.l 
[] 
>>> b.l 
[] 
>>> a.add(1) 
>>> a.l 
[1] 
>>> b.l 
[1] 
>>> c = test.Derived() 
>>> c.l 
[1] 

내가 기대 한 - 각 파생 된 개체는 기본 클래스의 고유 한 인스턴스를 포함하는 행동, "C++를 같이". 아직도 그렇습니까? 각 개체가 같은 목록 인스턴스를 공유하는 것처럼 보이는 이유는 무엇입니까?

+0

가능한 중복 (http://stackoverflow.com/questions/1132941/least-astonishment-in-python- the-mutable-default-argument) –

답변

14

일반적인 파이썬 초보자 실수입니다. How should I declare default values for instance variables in Python?

간단히 설명, 파이썬은 클래스 정의 한 번만 해석 :

여기에 내 대답을 참조하십시오. 즉, __init__() 메서드에서 선언 된 모든 내용은 한 번만 만들어집니다. 즉, [] 목록 기본 인수는 한 번만 작성됩니다.

self.l = l 그러면 참조이 새 클래스를 만들 때마다 동일한 인스턴스에 할당되므로 예상하지 못한 동작이 발생합니다.

파이썬 방법이 (부분 코드)입니다 : 또한

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

, 읽기 어렵다 l보다 더 나은 명명 규칙을 사용하는 것이 좋습니다 및 1 또는 |로 오인 될 수 있습니다.

+0

정답은 +1이지만 적어도 간단히 말해서 여기에 철자를 쓰면 좋을 것입니다. – Etaoin

+1

그럴 겁니다. ':]' –

+0

분명히 테스트 스 니펫입니다. 나는 결코 변수 이름으로 'l'을 선택하지 않을 것입니다. – tad

2

이것은 파이썬을 처음 사용하는 사람이 일반적으로 만들 수있는 변경 가능한 기본 인수 버그라고합니다. mutable을 기본 인수로 제공하면 기본 인수를 사용해야하는 경우 동일한 객체가 여러 인스턴스에서 사용됩니다. 는 IT가 초기화 호출의에서 더 나은 코드에서 http://docs.python.org/tutorial/controlflow.html#default-argument-values

중요 경고 섹션을 확인 이해 인스턴스가 사용되는 가변 기본 인자 (빈리스트 객체)을 얻을 당신은 B의 인스턴스를 만들 때 어떤 다시 Base의 init 메소드라고 불리는이 함수는 init에 사용 된 것과 동일한 객체를 다시 사용했다. 더 간단한 단어에서 a.l과 b.l은 같은 목록 객체를 가리 킵니다.

매우 유사한 토론 - "Least Astonishment" and the Mutable Default Argument

[파이썬에서 "최소 깜짝": 변경이 용이 한 기본 인수]의
+0

이것은 버그가 아니며 언어가 작동하는 방식입니다. –

관련 문제