2013-04-19 2 views
7

최근에 저는 official HOW-TO about Python descriptors을 읽었습니다. 실제로는 오래 전 Raymond Hettinger가 작성한 an essay에서 파생되었습니다. 그러나 여러 번 읽은 후에도 나는 그 부분에 대해 여전히 혼란 스럽습니다. 나는 약간의 단락을 인용 할 것이고, 뒤이어 나의 혼란과 질문이 올 것이다. 인스턴스의 사전 데이터 기술자와 같은 이름을 가진 항목이있는 경우파이썬 설명자와 <기술자 하우투 가이드>에 대한 혼란


는, 데이터 기술자가 우선합니다. 인스턴스의 사전에 비 데이터 디스크립터와 이름이 같은 항목이있는 경우 사전 항목이 우선 적용됩니다.

  • 이것은 클래스와 동일합니까? 사전에 데이터/비 데이터 설명 자와 같은 이름의 항목이있는 경우 클래스의 우선 순위 체인은 무엇입니까? 개체 용

는 기계에 type(b).__dict__['x'].__get__(b, type(b))b.x 변환 object.__getattribute__()이다. 구현은 인스턴스 변수에 비해 데이터 설명자를 우선시하고, 데이터가 아닌 디스크립터에 우선 순위가있는 인스턴스 변수를 제공하는 우선 순위 체인을 통해 작동하며, 제공된 경우 가장 낮은 우선 순위를 __getattr__()에 할당합니다.

클래스의 경우 기계류는 이고 B.xB.__dict__['x'].__get__(None, B)으로 변환됩니다.

  • 위의 두 단락

    는 속성 접속시 자동으로 호출되는 기술자의 존재의 과정을 말한다. 인스턴스 (b.x)와 클래스 (B.x)가 액세스하는 속성의 차이점을 나열합니다. 클래스의 속성 또는 인스턴스 기술자 아닌 경우 것이다 변환 여전히 진행 (즉, B.__dict__['x'].__get__(None, B)type(b).__dict__['x'].__get__(b, type(b))B.xb.x로 변환)
    • 그러나, 여기에 내 혼란인가? 이 클래스 또는 인스턴스의 속성을 dict으로 반환하는 것이 더 간단합니까?
    • 첫 번째 따옴표의 우선 순위 규칙에 따라 인스턴스의 사전에 비 데이터 설명자와 같은 이름의 항목이있는 경우 사전 항목이 우선 적용됩니다. 이때 변환은 계속 진행됩니까? 또는 dict의 값을 반환 하시겠습니까?

비 데이터 디스크립터 메소드에 바인딩 함수의 일반적인 패턴을 변화하기위한 간단한 메커니즘을 제공한다.

  • 는 기능/방법 만이 입수 할 수 있기 때문에 비 데이터 서술자가 선택되지만이을 설정할 수없는?
  • 함수를 메서드에 바인딩하는 기본 메커니즘은 무엇입니까?클래스 사전은 메소드를 함수로 저장하므로 클래스와 인스턴스를 각각 사용하여 동일한 메소드를 호출하면 기본 함수가 첫 번째 인수가 자체이어야하는지 여부를 어떻게 알 수 있습니까? 속성으로 액세스 할 때이 방법으로 변환 할 수 있도록

기능은 __get__() 방법이있다. 비 데이터 기술자는 obj.f(*args) 호출을 f(obj, *args)으로 변환합니다. klass.f(*args)을 호출하면 f (* args)가됩니다.

  • 방법이 아닌 데이터 기술자는 f(obj, *args)obj.f(*args) 전화를 변환 할 수 있습니까?
  • 비 데이터 설명자가 klass.f(*args) 전화를 f(*args)으로 변환 할 수 있습니까?
  • 위의 두 변형의 기본 메커니즘은 무엇입니까? 왜 클래스와 인스턴스간에 차이가 있습니까?
  • 위의 상황에서 __get__() 메서드는 어떤 역할을합니까?

답변

2

클래스와 동일합니까? 사전에 데이터/비 데이터 설명 자와 같은 이름의 항목이있는 경우 클래스의 우선 순위 체인은 무엇입니까?

아니요. 속성이 수퍼 클래스와 하위 클래스 모두에 정의되어 있으면 수퍼 클래스 값이 완전히 무시됩니다.

클래스 또는 인스턴스의 속성이 기술자가 아닌 경우는, 변환이 (즉, 여전히 진행 B.__dict__['x'].__get__(None, B))type(b).__dict__['x'].__get__(b, type(b)) 및 Bx로에 BX되는 TO 것인가?

아니, 직접 객체를 반환 모든 오브젝트가 기본 인수를 무시하고 self을 반환하는 방법 __get__()가있는 척하는 경우, 예, 클래스의 __dict__에서 얻었다. 또는 동등.

인스턴스의 사전에 첫 번째 인용문의 우선 순위 규칙에 따라 데이터가 아닌 디스크립터와 이름이 같은 항목이있는 경우 사전 항목이 우선 적용됩니다. 이때 변환은 계속 진행됩니까? 아니면 그 dict에있는 값을 반환할까요? 당신이 인용 한 단락에서 명확하지 않다 무엇

는 (아마도 다른 곳에서 아래로 쓰여) b.xb.__dict__['x']을 반환하기로 결정하면, 더 __get__는 어떤 경우에 호출되지 것입니다. __get__b.x 또는 B.x클래스 dict에있는 개체를 반환하기로 결정할 때 정확하게 호출됩니다.

함수/메소드는 가져올 수는 있지만 설정할 수 없기 때문에 데이터가 아닌 디스크립터가 선택 되었습니까?

예 : 그들은 f이 클래스 B에 살고 함수 객체는 함수 객체가 오버라이드 (override) 할 수있는 경우에도 사용자가 B.f = 42 말할 수있는 파이썬에서 "이전 스타일"클래스 모델의 일반화이다 무관 한 물체로 반면에 데이터 디스크립터는 property을 지원하기 위해 다른 로직을 가지고있다.

기능을 메소드에 바인딩하는 기본 메커니즘은 무엇입니까? 클래스 사전은 메소드를 함수로 저장하기 때문에 클래스와 인스턴스를 각각 사용하여 동일한 메소드를 호출하면 기본 함수가 첫 번째 인수가 자체가되어야하는지 여부를 어떻게 알 수 있습니까?

이것을 이해하려면 "메소드 객체"가 필요합니다. b.f(*args) 구문은 두 단계 인 (b.f)(*args)과 같습니다. 첫 번째 단계는 f.__get__(b)입니다. 이것은 b와 f를 저장하는 메쏘드 객체를 반환합니다. 두 번째 단계는 method 객체를 호출합니다. 메서드 객체는 b를 추가 인수로 추가하여 원본 f를 호출합니다. 이것은 B.f에 대해 발생하지 않는 것입니다. B.f, 즉 f.__get__(None, B)은 f (Python 3)입니다. 그것은 특별한 방법 __get__이 함수 객체에 대해 설계된 방법입니다.