您的解决方案是:
def save_last(f):
def w(*args, **kwargs): # w is the 'wrapper' function
w.last=f(*args, **kwargs)
return w.last
return w
@save_last
def fync(x): # just an example function
if 1<x<100: return (x%15 + x//6)*(x%2)
else: return (x%10)*10 + (x%7)
print 'fync.__dict__ :',fync.__dict__
for i in xrange(1,114):
if fync(i)%7==3:
print 'fync(%3d)==%2d %2d-3==%2d==7*%d' \
% (i,fync.last,fync.last,
fync.last-3,(fync.last-3)//7)
print 'fync.__dict__ :',fync.__dict__
结果
fync.__dict__ : {}
fync( 3)== 3 3-3== 0==7*0
fync( 9)==10 10-3== 7==7*1
fync( 35)==10 10-3== 7==7*1
fync( 41)==17 17-3==14==7*2
fync( 79)==17 17-3==14==7*2
fync( 85)==24 24-3==21==7*3
fync(102)==24 24-3==21==7*3
fync(109)==94 94-3==91==7*13
fync(113)==31 31-3==28==7*4
fync.__dict__ : {'last': 31}
.
我发现装饰器的使用很繁重,但可以这样做:
def finc(x):
if 1<x<100: finc.last = (x%15 + x//6)*(x%2)
else: finc.last = (x%10)*10 + (x%7)
return finc.last
print 'finc.__dict__ :',finc.__dict__
for i in xrange(1,114):
if finc(i)%7==3:
print 'finc(%3d)==%2d %2d-3==%2d==7*%d' \
% (i,finc.last, finc.last,
finc.last-3,(finc.last-3)//7)
print 'finc.__dict__ :',finc.__dict__
结果是完全一样的。
.
顺便说一句,我想象了以下解决方案:
def func(x=None,li=[None]):
if x is None: return li[0]
elif x>0:
if 1<x<100: li[0] = (x%15 + x//6)*(x%2)
else: li[0] = (x%10)*10 + (x%7)
return li[0]
for i in xrange(1,114):
if func(i)%7==3:
print 'func(%3d)==%2d %2d-3==%2d==7*%d' \
% (i,func(),func(),
func()-3,(func()-3)/7)
结果显然是一样的。
但我更喜欢上面的解决方案,在不使用装饰器的情况下使用属性。
.
诺塔贝内
所有三种解决方案的原理都是相同的:在返回结果之前将结果存储在函数中,无论是在属性中还是在默认参数列表中。
这就是将名称的创建从函数的外部转移到函数的内部:
无论如何,有必要有一个对象来存储结果,一个属性或一个列表,因此还需要一个专用的名称来保存访问存储对象。
那只是转移问题。
.
编辑
顺便说一句,我的最后一个解决方案(带有函数内部的列表)与以下另一个解决方案相距不远:
L = []
def fonc(x,li=L):
if 1<x<100: li[:] = [(x%15 + x//6)*(x%2)]
else: li[:] = [(x%10)*10 + (x%7)]
return li[0]
for i in xrange(1,114):
if fonc(i)%7==3:
print 'func(%3d)==%2d %2d-3==%2d==7*%d' \
% (i,L[0],L[0],
L[0]-3,(L[0]-3)/7)
但是此解决方案几乎等同于您在问题中所写的内容:由于绑定到tmp
标识符而保留函数的结果或将结果保留为列表的元素并没有太大区别。
所以我仍然是我的第一意见,你的问题是一个错误的问题:
.
if my_func(x) == some_value:
# do nothing with my_func(x)
return some_value