我正在使用来自其他网站的API,该网站会返回我的用户用来购买虚拟商品的几个“价格点网址”。
我应该将这些结果缓存至少一个小时,因为它们不会更改系统上的价格点。 (我们希望保存我们的带宽和带宽。)
在Python中查找单例后,我发现了borg模式,看起来更酷,所以这就是我所做的:
def fetchPrices():
#uses urllib2.urlopen() to fetch prices
#parses results with ElementTree
return prices
class PriceStore():
__shared_state = {}
def update(self):
if self.lastUpdate is not None and (datetime.now() - self.lastUpdate).seconds >= 3600:
self.prices = fetchPrices()
self.lastUpdate = datetime.now()
elif self.lastUpdate is not None:
return
else:
self.lastUpdate = datetime.now() - timedelta(hours=1)
self.update()
def __init__(self):
self.__dict__ = self.__shared_state
self.lastUpdate = None
self.update()
我们的想法是以下列方式使用它:
store = PriceStore()
url = store.prices['2.9900']['url']
如果现有信息超过一小时,商店应该正确初始化并且只获取新的价格信息。
每次PriceStore初始化时,我似乎都在点击他们的API。谁能发现我的问题?我可以在django中使用像__shared_state
这样的全局变量,并期望它仍然包含定价信息吗?
谢谢!
答案 0 :(得分:4)
我好像正在使用他们的API 每次PriceStore都是 尽管如此。谁能发现 我的问题?
是的,很容易发现:
def __init__(self):
self.__dict__ = self.__shared_state
self.lastUpdate = None
self.lastUpdate = None
绝对保证以后对self.update()
的调用会发现self.lastUpdate
的值为None
- 您只是强迫它如此!
删除self.lastUpdate = None
中的__init__
,例如,使用
lastUpdate = None
class body 级别,例如在__shared_state = {}
赋值之后,与该赋值具有相同的对齐方式。 那会让事情按照你的意愿运作。
答案 1 :(得分:1)
您的主要问题是,当您创建新的PriceStore时,您将self.lastUpdate设置为None(在倒数第二行)。因此,虽然它们都共享国家,但每个新对象都会破坏国家。
而是这样做:
class PriceStore():
__shared_state = {'lastUpdate': None}
您可能面临的另一个问题是,根据您的Django的部署方式,您可能正在使用多个进程。每个人都有自己的共享状态副本。
答案 2 :(得分:0)
在__init__
中设置self.lastUpdate = None
。不要那样做。
具体来说,请考虑以下代码:
A = PriceStore()
# some time later
B = PriceStore()
现在A.lastUpdate ==无,你不想要的!相反,尝试
if "lastUpdate" not in self.__dict__:
self.lastUpdate = None
这样你永远不会覆盖它。