当前,我使用以下技术:
def Myfb(param1, param2, firstTime):
if firstTime:
global a = compute()
global b = compute2()
global a
global b
c = doNormalExecution(param1, param2, a, b)
有没有更优雅的方式?我不喜欢创建全局变量
答案 0 :(得分:2)
该技术称为记忆。 functools模块具有一个lru_cache
函数,该函数可以执行您想要的操作。
from functools import lru_cache
@lru_cache(maxsize=None)
def Myfb(param1, param2):
b = doNormalExecution(a)
python文档具有更多信息,例如maxsize是什么以及lru_cache的工作方式,以便您可以适当地实现它。
答案 1 :(得分:0)
您可以使用生成器:
def Myfb():
a = compute()
while True:
param1, param2 = yield
b = doNormalExecution(a, param1, param2)
yield b
您在这里有一个live example
示例代码:
def compute():
return 10
def doNormalExecution(a, b, c):
return a + b + c
def Myfb():
a = compute()
while True:
param1, param2 = yield
b = doNormalExecution(a, param1, param2)
yield b
f = Myfb()
next(f)
for a, b in zip(range(10), range(10)):
print(f.send((a, b)))
next(f)
答案 2 :(得分:0)
您可以创建一个自定义可调用对象,以保持其自己的状态:
class MyFB(object):
_sentinel = object()
def __init__(self):
self._a = self._sentinel
self._b = self._sentinel
def __call__(self, param1, param2, reinit=False):
if reinit or self._a is self._sentinel or self._b is self._sentinel:
self._a = compute_a()
self._b = compute_b()
return doNormalExecution(param1, param2, self._a, self._b)
myfb = MyFB()
# now use `myfb` like an ordinary function
答案 3 :(得分:-2)
如果您没有将任何参数传递给函数,请使用此装饰器(我随处可见):
import functools
def lazy(func):
""" Decorator which only actually runs a function the first time it is
called and stores the result to be returned on later calls.
Usage:
@lazy
def func_to_be_only_run_once():
...
"""
FLAG = object()
result = FLAG
@functools.wraps(func)
def inner():
nonlocal result
if result is FLAG:
result = func()
return result
return inner
如果您有一个或多个更改的参数(包括self
),请使用functools.lru_cache
答案 4 :(得分:-2)
这是使用闭包的一种很酷的方法。
def closure(firstTime=True):
def Myfb():
nonlocal firstTime
if firstTime:
print("First time.")
firstTime = False
return Myfb
myfb = closure()
myfb()
myfb()