UFO ET IT

Python의 새 스타일 속성으로 '속성을 설정할 수 없습니다'

ufoet 2020. 11. 17. 21:27
반응형

Python의 새 스타일 속성으로 '속성을 설정할 수 없습니다'


새로운 스타일의 속성 선언을 사용하려고합니다.

class C(object):
    def __init__(self):
        self._x = 0

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

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

if __name__ == '__main__':
    c = C()
    print c.x
    c.x = 10
    print c.x

콘솔에서 다음을 참조하십시오.

pydev debugger: starting
getting
0
File "\test.py", line 55, in <module>
c.x = 10
AttributeError: can't set attribute

내가 도대체 ​​뭘 잘못하고있는 겁니까? 추신 : 구식 선언이 잘 작동합니다.


문서는 데코레이터 형식 사용에 대해 다음과 같이 말합니다property .

추가 함수에 원래 속성과 동일한 이름을 지정해야합니다 (이 경우 x).

property속성을 반환하기 위해 함수로 사용 하면 원하는대로 메서드를 호출 할 수 있기 때문에 이것이 왜 그런지 모르겠습니다 .

따라서 코드를 다음과 같이 변경해야합니다.

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

setter 메서드는 getter와 이름이 같아야합니다. 걱정하지 마세요. 데코레이터는 구분하는 방법을 알고 있습니다.

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

@ x.setter, @ x.getter 또는 @ x.deleter를 호출하면 새 속성 개체를 만들고 꾸미는 함수의 이름을 지정하게됩니다. 그래서 정말로 중요한 것은 클래스 정의에서 @ x. * er 데코레이터를 마지막으로 사용할 때 실제로 사용하려는 이름이 있다는 것입니다. 그러나 이렇게하면 사용하려는 속성의 불완전한 버전으로 인해 클래스 네임 스페이스가 오염되므로 동일한 이름을 사용하여 정리하는 것이 가장 좋습니다.


추가 _x이름 슬롯을 원하지 않는 경우 수행 할 수있는 복잡한 작은 트릭이 있습니다.
(Py34로 테스트 됨)

>>> class C(object):
    __slots__ = ['x'] # create a member_descriptor
    def __init__( self ):
        self.x = 0
        # or use this if you don't want to call x_setter:
        #set_x( self, 0 )


>>> get_x = C.x.__get__ # member_descriptor getter
>>> set_x = C.x.__set__ # member_descriptor setter
>>> # define custom wrappers:
>>> def x_getter( self ):
    print('getting')
    return get_x( self )

>>> def x_setter( self, value ):
    print('setting')
    set_x( self, value )


>>> C.x = property( x_getter, x_setter ) # replace the member_descriptor
>>> c = C()
setting
>>> print(c.x)
getting
0
>>> c.x = 10
setting
>>> 

참고 URL : https://stackoverflow.com/questions/4183432/cant-set-attribute-with-new-style-properties-in-python

반응형