首先是一段简化的代码,我将用它来解释这个问题.
def integrate(self, function, range):
# this is just a naive integration function to show that
# function needs to be called many times
sum = 0
for x in range(range):
sum += function(x) * 1
return sum
class Engine:
def __init__(self, capacity):
self.capacity = capacity
class Chasis:
def __init__(self, weigth):
self.weight = weight
class Car:
def __init__(self, engine, chassis):
self.engine = engine
self.chassis = chassis
def average_acceleration(self):
# !!! this calculations are actually very time consuming
return self.engine.capacity / self.chassis.weight
def velocity(self, time):
# here calculations are very simple
return time * self.average_acceleration()
def distance(self, time):
2 + 2 # some calcs
integrate(velocity, 2000)
2 + 2 # some calcs
engine = Engine(1.6)
chassis = Chassis(500)
car = Car(engine, chassis)
car.distance(2000)
chassis.weight = 600
car.distance(2000)
Run Code Online (Sandbox Code Playgroud)
Car是主要的班级.它有一个Engine和一个Chassis.
average_acceleration() 使用来自引擎和机箱的属性,并执行非常耗时的计算.
velocity()另一方面,执行非常简单的计算,但使用的计算值 average_acceleration()
distance()将velocity功能传递给integrate()
现在,integrate()多次velocity()打电话,每次打电话average_acceleration().考虑到返回的average_acceleration()值仅取决于Engine和Chassis,因此需要缓存返回的值average_acceleration().
我想以下列方式使用memoize装饰器:
@memoize
def average_acceleration(self, engine=self.engine, chassis=self.chassis):
# !!! this calculations are actually very time consuming
return engine.capacity / chassis.weight
Run Code Online (Sandbox Code Playgroud)
但它不会像我想的那样工作,因为发动机和底盘是可变的.因此,如果做:
chassis.weight = new_value
Run Code Online (Sandbox Code Playgroud)
average_acceleration()将在下一次调用时返回错误(先前缓存的)值.
最后我修改了代码如下:
def velocity(self, time, acceleration=None):
if acceleration is None:
acceleration = self.average_acceleration()
# here calculations are very simple
return time * acceleration
def distance(self, time):
acceleration = self.average_acceleration()
def velocity_withcache(time):
return self.velocity(time, acceleration)
2 + 2 # some calcs
integrate(velocity_withcache, 2000)
2 + 2 # some calcs
Run Code Online (Sandbox Code Playgroud)
我将参数添加acceleration到velocity()方法中.添加了该选项后,我acceleration只计算一次distance()方法,我知道底盘和引擎对象没有改变,我把这个值传递给了速度.
我写的代码完成了我需要它做的事情,但是我很好奇你是否能想出更好/更干净的东西?
| 归档时间: |
|
| 查看次数: |
549 次 |
| 最近记录: |