2012-04-01 6 views
4
class Silly: 
    @property 
    def silly(self): 
     "This is a silly property" 
     print("You are getting silly") 
     return self._silly 

    @silly.setter 
    def silly(self, value): 
     print("You are making silly {}".format(value)) 
     self._silly = value 

    @silly.deleter 
    def silly(self): 
     print("Whoah, you killed silly!") 
     del self._silly 

s = Silly() 
s.silly = "funny" 
value = s.silly 
del s.silly 

그러나 "바보 같이 보이고 있습니다."라는 말은 인쇄되지 않습니다. 이유를 모르겠다. 여러분, 제가 알아낼 수 있을까요?Python의 속성 꾸미기가 예상대로 작동하지 않습니다.

미리 감사드립니다.

답변

15

The property decoratornew-style classes (see also)과 만 작동합니다. Sillyobject에서 명시 적으로 확장하여 새 스타일 클래스로 만듭니다. 당신이 가장 가능성이 사용하는 것입니다 속성을 추가 할 수있는 올바른 방법을 알고있는대로

class Silly(object): 
    @property 
    def silly(self): 
     # ... 
    # ... 
+0

클래스 바보 -> 클래스 바보 (객체), 그리고했다. 나는 그것을 놓쳤다. 고맙습니다! – Locke

0

(파이썬 3에서, 모든 클래스는 새로운 스타일의 클래스입니다) :

@property 
def silly(self): 
    return self._silly 


@silly.setter: 
def silly(self, value): 
    self._silly = value 

을하지만이 새로운 스타일을 요구한다 클래스들, 즉 체인의 어딘가에는 class ParentClass(object):이 있어야합니다. silly = property(get_silly, set_silly)을 사용하는 비슷한 옵션에는 동일한 요구 사항이 있습니다.

그러나, 또 다른 옵션이며, 그것은 __getattr____setattr__ 방법을 self._silly처럼, 해당 개인 변수를 사용하고 무시하는 것입니다

def __getattr__(self, name): 
    """Called _after_ looking in the normal places for name.""" 

    if name == 'silly': 
     self._silly 
    else: 
     raise AttributeError(name) 


def __setattr__(self, name, value): 
    """Called _before_ looking in the normal places for name.""" 
    if name == 'silly': 
     self.__dict__['_silly'] = value 
    else: 
     self.__dict__[name] = value 

__getattr__이가 확인 후 를 호출하는 방법을 공지 사항 다른 속성을 확인하기 전에 __setattr__라고하고 다른 속성을 확인하십시오. 따라서 전자는 허용 된 속성이 아닌 경우 오류를 발생시킬 수 있고 발생시켜야하며 후자는 속성을 설정해야합니다. 이 아닌 self._silly = value__setattr__과 같이 사용하면 무한 재귀가 발생합니다.

여기에서 구식 클래스를 다루므로 실제로는 dict 메서드를 사용해야하며 baseclass.__setattr__(self, attr, value)은 더 최신이 아니라 docs을 참조하십시오. 원한다면 비슷한 __delattr__()도 존재합니다.

이 코드를 사용하여, 당신은 지금 물건처럼 수행 할 수 있습니다

i_am = Silly() 
i_am.silly = 'No, I'm clever' 
print i_am.silly