2011-09-01 3 views
-1

이것은 몇 가지 포인트를 얻는 쉬운 방법입니다. 설명해주십시오 다음클래스와 인스턴스 변수로 사전 및 배열

10 20 10 10 
20 20 20 10 

왜 사전, 목록과 '일반'변수 각각 다르게 작동 않습니다 다음

class C: 
    a = {} 
    b = 0 
    c = [] 

    def __init__(self): 
     self.x = {} 

    def d(self, k, v): 
     self.x[k] = v 
     self.a[k] = v; 
     self.b = v 
     self.c.append(v) 

    def out(self, k): 
     print(self.x[k], self.a[k], self.b, self.c[0]) 

c = C() 
d = C() 
c.d(1, 10) 
d.d(1, 20) 
c.out(1) 
d.out(1) 

윌 출력?

편집 : 나는 질문이 분명하다 생각하지만, 나를 더 자세히 철자하게되었다

나는 세 가지 속성, A, B 및 C와 클래스가 있습니다. 클래스의 두 인스턴스를 만듭니다. 그런 다음 각 인스턴스에 대해 이러한 특성을 수정하는 메서드를 호출합니다. 속성을 검사 할 때 속성이 사전 인 경우 모든 인스턴스에서 공유되는 반면 '평범한'변수 인 경우 속성은 예상대로 동작하며 각 인스턴스마다 다릅니다.

+0

"왜 사전, 배열 및 '일반'변수가 각각 다르게 동작합니까?" 그들은 다른 수업이기 때문에 다르게 행동합니다. 그 질문은 전혀 이해가되지 않습니다. 어떤 ** 특정 ** 차이점에 대해 알고 싶습니까? –

답변

5

먼저 이해해야합니다, []는 목록의 배열이 아닙니다. 여기서 문제는 속성 분석과 가변 변수가 작동하는 방식입니다. 이 세 가지 속성을 가진 클래스를 만듭니다

class Foo(object): 
    a = {} 
    b = 0 
    c = [] 

으로 시작하자 - 사람들은, 또는 인스턴스 (Foo().a) '클래스를 통해 (예를 들어, Foo.a) 중 하나를 클래스 자체를 통해 사용할 수 있습니다. 속성은 __dict__이라는 특수한 것으로 저장됩니다. 클래스와 인스턴스 모두 하나를 가지고 있지만 (사실이 아니지만 여기서는 관련이 없습니다) - Foo의 경우 인스턴스가 생성 될 때 __dict__ 인스턴스는 비어 있습니다. 따라서 Foo().a을 수행 할 때, 실제로는 Foo.a과 같은 객체에 액세스하고 있습니다.

이제 __init__이 추가됩니다.

class Foo(object): 
    # ... 

    def __init__(self): 
     self.x = {} 

이하지 클래스 '__dict__의 속성을 생성하지만 인스턴스 하나, 당신은 Foo.xFoo().x에 액세스 할 수 있습니다. 이는 또한 모든 인스턴스에서 x이 완전히 다른 객체라는 것을 의미하는 반면 클래스 속성은 모든 클래스 인스턴스에서 공유됩니다.

이제 돌연변이 방법을 추가하고 있습니다.

class Foo(object): 
    # ... 

    def mutate(self, key, value): 
     self.x[key] = value 
     self.a[key] = value 
     self.b  = value 
     self.c.append(value) 

self.x = {}은 인스턴스 속성을 만듭니다. 여기 self.b = value은 똑같은 일을합니다. 클래스 속성에 전혀 영향을 미치지 않습니다. 인스턴스에 대한 공유 된 속성을 무시합니다 (참조가 파이썬에서 작동하는 방식 임). 할당은 이름을 객체에 바인딩하고 수정하지 않습니다. 이름이 가리키는 오브젝트)

self.c을 리 바인드하지 않아도됩니다. (변경 가능하고 실제로 할 수 있기 때문에) 원래 클래스 속성을 수정하고 있기 때문에 실제로 볼 수 있습니다 다른 인스턴스의 변화 (그들에 의해 공유되는 것처럼).self.x은 클래스 속성이 아니기 때문에 다르게 동작합니다. 인스턴스 속성이 아닙니다.

또한 첫 번째 요소 인 self.c 만 인쇄합니다. 모든 요소를 ​​인쇄 할 경우 [10, 20]이 표시됩니다.

+0

만약 당신이 올바르게 이해한다면, 그것은 다음과 같이 요약 할 수 있습니다.'self.b = value'는'instance.__ dict__'에 새로운 항목을 만들고'self.a [key] = value'는 새로운 항목을 만듭니다. 나는 내 질문에 대한 대답이라고 생각합니다 : 인스턴스가 생성 될 때 인스턴스 사전은 채워지지 않고 속성이 할당 될 때만 채워집니다. 이 올바른지? – martin

+0

@ 마틴 : 예. 기본 getattr은 먼저 인스턴스 dict를 확인한 다음 속성이 발견되지 않으면 클래스 dict를 검사합니다 (+ bases 및 stuff이지만 기본적으로 this). –

관련 문제