문제

그래서 저는 Python 2.6에서 데코레이터를 가지고 놀고 있으며, 일을하는 데 어려움을 겪고 있습니다. 내 수업 파일은 다음과 같습니다.

class testDec:

    @property
    def x(self): 
        print 'called getter'
        return self._x

    @x.setter
    def x(self, value): 
        print 'called setter'
        self._x = value

내가 생각한 것은 치료하는 것입니다 x 속성과 마찬가지로이 기능을 Get and Set에서 호출하십시오. 그래서 나는 유휴 상태를 발사하고 확인했습니다.

>>> from testDec import testDec
from testDec import testDec
>>> t = testDec()
t = testDec()
>>> t.x
t.x
called getter
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "testDec.py", line 18, in x
    return self._x
AttributeError: testDec instance has no attribute '_x'
>>> t.x = 5
t.x = 5
>>> t.x
t.x
5

분명히 첫 번째 호출은 Getter를 호출하기 때문에 예상대로 작동하며 기본값이 없으며 실패합니다. 좋아, 좋아, 이해한다. 그러나 할당 요청 t.x = 5 새로운 재산을 만드는 것 같습니다 x, 그리고 이제 Getter가 작동하지 않습니다!

내가 무엇을 놓치고 있습니까?

도움이 되었습니까?

해결책

당신은 사용중인 것 같습니다 고전적인 구식 수업 Python 2에서 속성 올바르게 작동하려면 사용해야합니다 새로운 스타일의 수업 대신 (Python 2에서는 당신이해야합니다 상속 object). 수업을 그냥 선언하십시오 MyClass(object):

class testDec(object):

    @property
    def x(self): 
        print 'called getter'
        return self._x

    @x.setter
    def x(self, value): 
        print 'called setter'
        self._x = value

효과가있다:

>>> k = testDec()
>>> k.x
called getter
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/devel/class_test.py", line 6, in x
    return self._x
AttributeError: 'testDec' object has no attribute '_x'
>>> k.x = 5
called setter
>>> k.x
called getter
5
>>> 

문제를 일으킬 수있는 또 다른 세부 사항은 두 방법 모두 재산이 작동하려면 동일한 이름이 필요하다는 것입니다. 이와 같은 다른 이름으로 세터를 정의하면 작동하지 않습니다.:

@x.setter
def x_setter(self, value):
    ...

그리고 처음에는 완전히 쉽게 찾을 수없는 한 가지는 순서입니다 : The Getter 먼저 정의해야합니다. 세터를 먼저 정의하면 얻을 수 있습니다 name 'x' is not defined 오류.

다른 팁

이 예외를 찾고있는 다른 사람들을위한 메모입니다. 두 기능 모두 같은 이름이 필요합니다. 다음과 같이 메소드의 이름을 지정하면 예외가 발생합니다.

@property
def x(self): pass

@x.setter
def x_setter(self, value): pass

대신 두 가지 메소드에 동일한 이름을 부여하십시오

@property
def x(self): pass

@x.setter
def x(self, value): pass

또한 선언의 순서가 중요하다는 점에 유의해야합니다. getter는 파일의 세터 전에 정의해야합니다. 그렇지 않으면 NameError: name 'x' is not defined

객체에서 수업을 도출하여 수행하는 새로운 스타일 클래스를 사용해야합니다.

class testDec(object):
   ....

그런 다음 작동해야합니다.

누군가 Google에서 여기에 오면 위의 답변 외에도 Setter를 호출 할 때주의를 기울여야한다고 덧붙이고 싶습니다. __init__ 당신의 수업의 방법을 기반으로합니다 이 답변구체적으로:

class testDec(object):                                                                                                                                            

    def __init__(self, value):
        print 'We are in __init__'
        self.x = value # Will call the setter. Note just x here
        #self._x = value # Will not call the setter

    @property
    def x(self):
        print 'called getter'
        return self._x # Note the _x here

    @x.setter
    def x(self, value): 
        print 'called setter'
        self._x = value # Note the _x here

t = testDec(17)
print t.x 

Output:
We are in __init__
called setter
called getter
17
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top