2017-10-02 4 views
1

파이썬 2.7을 사용하여 아래 정의 된 새로운 스타일 클래스 구문을 사용하는 클래스가 있다고 가정합니다.새 스타일 클래스와 이전 스타일 클래스에서 setter가 다르게 작동하는 이유

class Test(object): 
    def __init__(self): 
    self._a = 5 

    @property 
    def a(self): 
    return self._a 

    @a.setter 
    def a(self, val): 
    self._a = val 

t = Test() 
print t.a 
t.a = 4 
print t.a 
print t._a 

위의 코드를 실행하면 5,4,4이 원하는 동작으로 인쇄됩니다. 그러나 위 코드의 첫 줄을 class Test:으로 변경하면 결과는 5,4,5이됩니다.

출력에이 차이가 나는 원인을 알고있는 사람이 있습니까?

답변

2

설명자는 이며 구식 클래스에 대해 호출 할 수 없습니다. docs에서 :

속성 액세스를위한 기본 동작은 설정 얻을, 또는 객체의 사전에서 속성을 삭제하는 것입니다. 예를 들어, a.xa.__dict__['x']으로 시작하고 으로 시작하고 type(a) 메타 클래스를 제외한 기본 클래스를 통해 계속되는 조회 체인을가집니다. 조회 된 값이 설명자 메소드 중 하나를 정의하는 객체 인 경우 Python은 기본 비헤이비어를 무시하고 대신 설명자 메소드를 호출 할 수 있습니다. 이 이 우선 순위 체인에서 발생하는 경우 정의 된 설명자 방법에 따라 다릅니다. 설명자는 새 스타일 개체 또는 클래스 (개체에서 상속 된 경우 클래스는 새 스타일이거나 유형)에 대해서만 호출됩니다.

그럼, 여기에 무슨 것은 Test.a.__set__가 호출되고 있지 않습니다 있다는 것입니다, 당신은 단순히 추가 a 속성 t에 : 정말 T.a.__get__ 작업을 수행 왜 입니다 놀라게한다 무엇

In [8]: class Test: 
    ...: def __init__(self): 
    ...:  self._a = 5 
    ...: 
    ...: @property 
    ...: def a(self): 
    ...:  return self._a 
    ...: 
    ...: @a.setter 
    ...: def a(self, val): 
    ...:  self._a = val 
    ...: 

In [9]: t = Test() 

In [10]: vars(t) 
Out[10]: {'_a': 5} 

In [11]: t.a 
Out[11]: 5 

In [12]: t._a 
Out[12]: 5 

In [13]: t.a = 100 

In [14]: t.a 
Out[14]: 100 

In [15]: t._a 
Out[15]: 5 

In [16]: vars(t) 
Out[16]: {'_a': 5, 'a': 100} 

여기에 모두?

그 대답은 파이썬 2.2에서 이전 스타일의 클래스가 설명자를 사용하기 위해 다시 구현되었으며, 이는 의존해서는 안되는 구현 세부 사항입니다. this 질문 및 issue 링크를 참조하십시오.

요약 설명자를 사용하는 경우 새로운 스타일의 클래스에서만 사용해야합니다. 나는 새로운 스타일의 클래스를 사용하는 경우에

참고, 그것을 작동 예상대로 :

In [17]: class Test(object): 
    ...: def __init__(self): 
    ...:  self._a = 5 
    ...: 
    ...: @property 
    ...: def a(self): 
    ...:  return self._a 
    ...: 
    ...: @a.setter 
    ...: def a(self, val): 
    ...:  self._a = val 
    ...: 

In [18]: t = Test() 

In [19]: vars(t) 
Out[19]: {'_a': 5} 

In [20]: t.a = 100 

In [21]: t.a 
Out[21]: 100 

In [22]: t._a 
Out[22]: 100 

In [23]: vars(t) 
Out[23]: {'_a': 100}