给定一个昂贵的初始化对象和 2 个消费者:
class A:
def __init__():
time.sleep(42)
self.foo = 1
def func1(obj: A):
pass
def func2(obj: A):
print(A.foo)
如何创建一个
wrapper
来延迟 A
的初始化,直到访问其任何字段为止?
proxy = wrapper(A)
func1(proxy) # executes immediately
func2(proxy) # causes object initialization and waits 42 seconds.
换句话说,如何延迟对象初始化,直到以传统方式访问其任何属性为止
a.foo
或者最坏的情况是a.__dict__['foo']
。
您可以为此编写一个通用装饰器。假设您将一个名为
__lazyinit__
的函数添加到您的类中,此装饰器将确保在每个需要对象完全初始化的装饰方法之前调用它。
def lazyinit(f):
def doInit(self,*args,**kwargs):
self.__lazyinit__()
return f(self,*args,**kwargs)
return doInit
class A:
def __init__(self,p1,p2):
self._p1 = p1
self._p2 = p2
self._initComplete = False
def __lazyinit__(self):
if self._initComplete: return
self._p3 = self._p1 + self._p2
self._initComplete = True
@lazyinit # works for functions
def funcX(self):
print(self._p3)
@property
@lazyinit # also works for properties
def p3(self):
return self._p3
示例:
a = A(2,3)
a._p3 # Attribute Error
a.funcX() # prints 5
a2 = A(4,5)
a2._p3 # Attribute Error
print(a2.p3) # prints 9