목표는 애트리뷰트의 lazyloading을 허용하는 커스텀 파이썬 클래스를 만드는 것이다. 게으른 액세스. 여기 예제 :이 예에서퍼스트 클래스 애트리뷰트 액세스시 파이썬 커스텀 초기화
class LazyDateModule()
def __init__(self, args):
self.args = args
self._expensive_date_attr = None
def _expensive_init():
time.sleep(10)
self._expensive_date_attr = date.today()
@memoize
def date_str():
return str(self._expensive_date_attr)
@memoize
def month_num():
return self._expensive_date_attr.month
, 내 @memoize
장식 나를 위해 캐싱 단계를 처리합니다.
나는 다른 곳에서 내 LazyDateModule를 정의하고있어 경우
LDM = LazyDateModule()
어떻게 만 memoized 속성 방법 중 하나에 액세스 한 처음에
_expensive_init()
를 실행합니까? 나는 이와 같은 것을 시도했다 :
class LazyDateModule()
def __init__(self, args):
self.args = args
self._assembled = False
self._expensive_date_attr = None
def _expensive_init():
time.sleep(10)
self._expensive_date_attr = date.today()
self._assembled = True
@memoize
def date_str():
if self._assembled is False:
self._expensive_init()
return str(self._expensive_date_attr)
@memoize
def month_num():
if self._assembled is False:
self._expensive_init()
return self._expensive_date_attr.month
그러나 그것은 매우 깨끗하지 않다. 이상적으로는이 동작을 클래스 수준에서 사용하길 원하지만, __getattr__
또는 __getattribute__
을 덮어 쓰려는 시도에서 고생했습니다. 다른 데코레이터도 사용할 수 있습니다.
위의 내용이 혼란 스럽다면 죄송합니다. 내가 그것을 어떤 방식 으로든 분명히 할 수 있다면 알려줘!
편집 1 : 위의 예는 너무 간단하다고 생각합니다. 내 _expensive_init()가 단일 속성을 정의하는 것과는 대조적으로 많은 작업을 수행한다고 가정 해 보겠습니다.
def _expensive_init(self):
time.sleep(5)
self._expensive_date_attr = date.today()
time.sleep(1)
# send a message to someone saying that this occurred
time.sleep(1)
# run a db call to update when this action occurred
etc...
이 메서드는 다양한 동작을 처리하는 것이 가장 이상적입니다.
나는 비슷한 모듈을 썼다. 나는 그것을 끝내지 않기로 결정했다. 그것은 두 단계로 진행되었습니다. 첫 번째 단계에서 간단한 메소드 데코레이터는 데코 레이팅 된 함수 자체에 속성을 추가하여 메모 할 모든 메소드를 등록합니다. 그 당시에는 클래스 자체가 존재하지 않기 때문에 이것이 모두 가능합니다. 두 번째 단계에서 클래스 데코레이터는 추가 된 속성에 대한 모든 메소드를 검사하고, 테이블을 만들고, 클래스에서 해당 메소드를 제거하고, 테이블의 이름에 대한 첫 번째 액세스를 포착하고 함수를 호출하고 결과를 일반 속성으로 표시합니다. 희망이 도움이됩니다. – VPfB