如何在Python中创建延迟初始化(代理)包装器?

问题描述 投票:0回答:1

给定一个昂贵的初始化对象和 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']

python proxy lazy-initialization
1个回答
0
投票

您可以为此编写一个通用装饰器。假设您将一个名为

__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
© www.soinside.com 2019 - 2024. All rights reserved.