這是一個簡單的緩存修飾器。它沒有考慮到參數的任何變化,它只是在第一次調用之後返回相同的結果。有更奇特的緩存每個輸入組合的結果(「記憶」)。
import functools
def callonce(func):
result = []
@functools.wraps(func)
def wrapper(*args, **kwargs):
if not result:
result.append(func(*args, **kwargs))
return result[0]
return wrapper
用法:
@callonce
def long_running_function(x, y, z):
# do something expensive with x, y, and z, producing result
return result
如果你希望寫你的功能出於某種原因(可能的結果是在每次調用略有不同,但仍然是一個費時的初始設置的發電機,否則你只是想要C風格的靜態變量,讓你的函數要記住從一個呼叫狀態的某些位到下),你可以使用這個裝飾:
import functools
def gen2func(generator):
gen = []
@functools.wraps(generator)
def wrapper(*args, **kwargs):
if not gen:
gen.append(generator(*args, **kwargs))
return next(gen[0])
return wrapper
用法:
@gen2func
def long_running_function_in_generator_form(x, y, z):
# do something expensive with x, y, and z, producing result
while True:
yield result
result += 1 # for example
一個Python 2.5或更高版本使用.send()
允許參數傳遞給發電機的每次迭代如下(注意:**kwargs
不支持):
import functools
def gen2func(generator):
gen = []
@functools.wraps(generator)
def wrapper(*args):
if not gen:
gen.append(generator(*args))
return next(gen[0])
return gen[0].send(args)
return wrapper
@gen2func
def function_with_static_vars(a, b, c):
# time-consuming initial setup goes here
# also initialize any "static" vars here
while True:
# do something with a, b, c
a, b, c = yield # get next a, b, c
爲什麼不只是緩存結果在變量或函數屬性?或者查看一下您可以通過Google找到的其中一種Python備忘錄配方。 – user2357112
@ user2357112注意。兩個都在答案中提到。 – 2rs2ts
我無法弄清楚你的名字,有沒有什麼我沒有得到?對於ts ?,這是2complicated4me – Stephan