질문 : @property 데코레이터는 파이썬에서 어떻게 작동합니까?
property
어떻게 작동하는지 이해하고 싶습니다. 나를 혼란스럽게하는 것은 property
을 데코레이터로도 사용할 수 있지만, 내장 함수로 사용할 때만 인수를 사용하고 데코레이터로 사용할 때는 인수를 사용하지 않는다는 것입니다.
이 예는 문서 에서 가져온 것입니다.
class C:
def __init__(self):
self._x = None
def getx(self):
return self._x
def setx(self, value):
self._x = value
def delx(self):
del self._x
x = property(getx, setx, delx, "I'm the 'x' property.")
property
의 인수는 getx
, setx
, delx
및 doc 문자열입니다.
아래 코드에서 property
은 데코레이터로 사용됩니다. 객체는 x
함수이지만 위의 코드에서는 인수에 객체 함수를위한 위치가 없습니다.
class C:
def __init__(self):
self._x = None
@property
def x(self):
"""I'm the 'x' property."""
return self._x
@x.setter
def x(self, value):
self._x = value
@x.deleter
def x(self):
del self._x
이 경우 x.setter
및 x.deleter
데코레이터는 어떻게 생성됩니까?
답변
property()
함수는 특수 설명자 객체를 반환합니다.
>>> property()
<property object at 0x10ff07940>
추가 메서드가있는 것은이 개체입니다.
>>> property().getter
<built-in method getter of property object at 0x10ff07998>
>>> property().setter
<built-in method setter of property object at 0x10ff07940>
>>> property().deleter
<built-in method deleter of property object at 0x10ff07998>
이것들은 장식 자 역할 도 합니다. 새 속성 개체를 반환합니다.
>>> property().getter(None)
<property object at 0x10ff079f0>
이전 개체의 복사본이지만 함수 중 하나가 교체되었습니다.
@decorator
구문은 단지 구문 적 설탕이라는 것을 기억하십시오. 구문 :
@property
def foo(self): return self._foo
정말 같은 의미
def foo(self): return self._foo
foo = property(foo)
그래서 foo
함수는 위에서 본 특별한 객체 인 property(foo)
로 대체됩니다. @foo.setter()
를 사용할 때 property().setter
메서드를 호출하여 속성의 새 복사본을 반환하지만 이번에는 setter 함수를 데코 레이팅 된 메서드로 바꿉니다. .
다음 시퀀스는 이러한 데코레이터 메서드를 사용하여 전체 속성을 만듭니다.
먼저 getter만으로 몇 가지 함수와 property
>>> def getter(self): print('Get!')
...
>>> def setter(self, value): print('Set to {!r}!'.format(value))
...
>>> def deleter(self): print('Delete!')
...
>>> prop = property(getter)
>>> prop.fget is getter
True
>>> prop.fset is None
True
>>> prop.fdel is None
True
다음으로 .setter()
메서드를 사용하여 setter를 추가합니다.
>>> prop = prop.setter(setter)
>>> prop.fget is getter
True
>>> prop.fset is setter
True
>>> prop.fdel is None
True
마지막으로 .deleter()
메서드를 사용하여 삭제자를 추가합니다.
>>> prop = prop.deleter(deleter)
>>> prop.fget is getter
True
>>> prop.fset is setter
True
>>> prop.fdel is deleter
True
마지막으로 property
객체는 설명자 객체 역할을하므로 .__get__()
, .__set__()
및 .__delete__()
메서드를 사용하여 인스턴스 속성 가져 오기, 설정 및 삭제에 연결합니다.
>>> class Foo: pass
...
>>> prop.__get__(Foo(), Foo)
Get!
>>> prop.__set__(Foo(), 'bar')
Set to 'bar'!
>>> prop.__delete__(Foo())
Delete!
Descriptor Howto에는 property()
유형 의 순수 Python 샘플 구현 이 포함되어 있습니다.
class Property:
"Emulate PyProperty_Type() in Objects/descrobject.c"
def __init__(self, fget=None, fset=None, fdel=None, doc=None):
self.fget = fget
self.fset = fset
self.fdel = fdel
if doc is None and fget is not None:
doc = fget.__doc__
self.__doc__ = doc
def __get__(self, obj, objtype=None):
if obj is None:
return self
if self.fget is None:
raise AttributeError("unreadable attribute")
return self.fget(obj)
def __set__(self, obj, value):
if self.fset is None:
raise AttributeError("can't set attribute")
self.fset(obj, value)
def __delete__(self, obj):
if self.fdel is None:
raise AttributeError("can't delete attribute")
self.fdel(obj)
def getter(self, fget):
return type(self)(fget, self.fset, self.fdel, self.__doc__)
def setter(self, fset):
return type(self)(self.fget, fset, self.fdel, self.__doc__)
def deleter(self, fdel):
return type(self)(self.fget, self.fset, fdel, self.__doc__)
출처 : https://stackoverflow.com/questions/17330160/how-does-the-property-decorator-work-in-python
'프로그래밍 언어 > Python' 카테고리의 다른 글
Python의 경로에서 확장자없이 파일 이름을 얻는 방법 (0) | 2021.06.29 |
---|---|
Python에서 "with open"을 사용하여 여러 파일을 여는 방법 (0) | 2021.06.28 |
파이썬의 순서 집합 (0) | 2021.06.25 |
사람들이 파이썬 스크립트의 첫 번째 줄에 #! / usr / bin / env python을 쓰는 이유 (0) | 2021.06.25 |
ISO 8601 datetime 문자열을 Python datetime 객체로 변환하는 방법 (0) | 2021.06.24 |