"""Object Utilities."""from__future__importannotationsfromthreadingimportRLock__all__=('cached_property',)try:fromfunctoolsimportcached_propertyas_cached_propertyexceptImportError:# TODO: Remove this fallback once we drop support for Python < 3.8fromcached_propertyimportthreaded_cached_propertyas_cached_property_NOT_FOUND=object()
[文档]classcached_property(_cached_property):"""Implementation of Cached property."""def__init__(self,fget=None,fset=None,fdel=None):super().__init__(fget)self.__set=fsetself.__del=fdelifnothasattr(self,'attrname'):# This is a backport so we set this ourselves.self.attrname=self.func.__name__ifnothasattr(self,'lock'):# Prior to Python 3.12, functools.cached_property has an# undocumented lock which is required for thread-safe __set__# and __delete__. Create one if it isn't already present.self.lock=RLock()def__get__(self,instance,owner=None):# TODO: Remove this after we drop support for Python<3.8# or fix the signature in the cached_property packagewithself.lock:returnsuper().__get__(instance,owner)def__set__(self,instance,value):ifinstanceisNone:returnselfwithself.lock:ifself.__setisnotNone:value=self.__set(instance,value)cache=instance.__dict__cache[self.attrname]=valuedef__delete__(self,instance):ifinstanceisNone:returnselfwithself.lock:value=instance.__dict__.pop(self.attrname,_NOT_FOUND)ifself.__delandvalueisnot_NOT_FOUND:self.__del(instance,value)