2014-07-01 2 views
2

제목에 나와 있습니다. 내가하는 일에 상관없이, __getattr__은 호출되지 않을 것입니다. 나도 예를 들어 그것을 시도했다 (어리석은, 나는 알고있다). 마치 __getattr__이 메타 클래스에서 금지 된 것처럼.메타 클래스가 호출되지 않는 __getattr__이

이에 대한 문서에 대한 포인터를 알려 주시면 감사하겠습니다.

코드 : 속성이 존재하지 않는 경우

class PreinsertMeta(type): 

    def __getattribute__(self, attrname): 
     if attrname == "field" and isinstance(object.__getattribute__(self, attrname), basestring): 
      tbl, fld = object.__getattribute__(self, attrname).split(".") 
      self.field = (tbl, fld) 
     return object.__getattribute__(self, attrname) 

답변

4

documented으로 __getattr__ 만 호출됩니다 BrenBarn에

class PreinsertMeta(type): 

    def resolvedField(self): 
     if isinstance(self.field, basestring): 
      tbl, fld = self.field.split(".") 
      self.field = (tbl, fld) 
     return self.field 

    Field = property(resolvedField) 

    def __getattr__(self, attrname): 
     if attrname == "field": 
      if isinstance(self.field, basestring): 
       tbl, fld = self.field.split(".") 
       self.field = (tbl, fld) 
      return self.field 
     else: 
      return super(PreinsertMeta, self).__getattr__(attrname) 

    def __setattr__(self, attrname, value): 
     super(PreinsertMeta, self).__setattr__(attrname, value) 


class Test(object): 
    __metaclass__ = PreinsertMeta 
    field = "test.field" 

print Test.field # Should already print the tuple 
Test.field = "another.field" # __setattr__ gets called nicely 
print Test.field # Again with the string? 
print Test.Field # note the capital 'F', this actually calls resolvedField() and prints the tuple 

감사합니다, 여기에 최종 작업을 구현합니다. 수업에는 field 속성이 있으므로 __getattr__을 차단합니다. 모든 속성 액세스를 가로 채고 싶다면 __getattribute__을 사용할 수 있습니다. 이유에 대해 분명히 알지 못하지만이 작업을 수행해야하는 이유는 분명하지 않습니다. 이것은 메타 클래스와 아무런 관련이 없다. 평범한 클래스의 인스턴스를 만들고 속성을 주면 같은 동작을 볼 수 있습니다.

__getattribute__을 사용한다고 가정해도 특성이 존재할 때 호출되었으므로 구현이 의미가 없습니다. __getattr__ 안에 self.field의 값을 가져 오십시오. 그러나 __getattribute__이 처음에 호출 된 경우이 호출에 대해 무한 재귀를 호출하여 self.field을 얻으려면 __getattribute__을 호출해야하며 다시 self.field을 호출합니다. 다시 __getattribute__ 등이 호출됩니다. 이 문제를 해결하는 방법은 __getattribute__documentation을 참조하십시오.

+0

감사합니다.'__getattribute__'도 잊어 버렸습니다. :) 그리고 위의 구현은 부모 클래스의 하위 클래스를위한 것이며,'field' 멤버는 기본 클래스 멤버를 직접 참조 할 수 없습니다. 그 당시에는 존재하지 않습니다. __getattribute__ 버전을 사용하면 사용시 해결 된 멤버 변수를 사용할 수 있습니다. 포함하거나 하위 클래스가 인스턴스화되지 않았으므로 메타 클래스를 사용하여이 작업을 시도합니다. – velis

관련 문제