就我而言,我在 file1 中初始化并使用这些(复杂且昂贵的)对象,将它们导入到 file2 中并使用。它不会浪费时间在两个文件的多个函数中创建多个 obj,并且对我有用。
# utils.py
from fancy_module import Fancy_class
expensive_obj = Fancy_class()
def func1():
expensive_obj.do_stuff()
# work.py
from utils import func1, expensive_obj
def work_func():
expensive_obj.do_other_stuff()
然而,当我将其交给同事部署时,他指出导入过程中需要相当长的时间才能完成
expensive_obj = Fancy_class()
,并且这会给我们正在使用的产品框架带来麻烦(我无法更改这一点)。他要求将其放入 getter 中并使用 @lru_cache 以避免重复。
# utils.py
from fancy_module import Fancy_class
@lru_cache
def get_expensive_obj():
return Fancy_class()
def func1():
expensive_obj = get_expensive_obj()
expensive_obj.do_stuff()
# work.py
from utils import func1, get_expensive_obj
def work_func():
expensive_obj = get_expensive_obj()
expensive_obj.do_other_stuff()
不知道lru_cache到底是如何工作的,我担心它是否真的能避免重复
expensive_obj
。另外,我需要在大约几十个类似于 func1() 和 work_founc() 的函数中创建一些像这样的 expensive_obj
。有点乱。
还有其他解决方案可以让我:
谢谢!!
如果您不确定
@lru_cache
并且只需要 Fancy_Class
的单个实例,那么您可以使用此方法执行手动记忆。
class Fancy_Class:
@(lambda _:_()) # invokes the outer-part of getInstance at run-time
def get_expensive_object():
_expensive_object = None # do not touch
@staticmethod
def inner():
""" returns a cached instance on Fancy_Class """
nonlocal _expensive_object
if (_expensive_object):
return _expensive_object
_expensive_object=Fancy_Class()
return _expensive_object
return inner
...
这实现了与示例中的
get_expensive_object
相同的结果,唯一的区别是它是其中包含单个值的(伪)缓存存储的手动实现。另外,我还建议将 get_expensive_object
方法封装在 Fancy_Class
中,这样就可以清楚地看出该函数与 Fancy_Class
相关(并且您不必担心单独导入该函数)。
如果您计划将来能够将参数传递给
getInstance
函数,我建议使用 cache
或 @lru_cache
装饰器,而不是像我那样手动创建缓存(即时调用函数表达式,如我上面使用的东西通常只在像 JS 这样的原型语言中出现)。
@cache
和@lru_cache
如何工作(注意:我已包含此部分,因为您似乎不确定
lru_cache
的工作原理)
cache(typed=False)
缓存根据传递的参数对函数进行的每个调用。如果 typed
设置为 True
那么它将根据参数的哈希值和类型来缓存参数。 lru_cache(maxsize=128, typed=False)
与 @cache
类似,其目的是 cache
只会增长到 maxsize
项目的最大尺寸。一旦达到 maxsize,这些项目将使用 LRU 策略从缓存中删除。如果 maxsize
设置为 None
,则 @lru_cache
的行为就像 @cache
。