2015-10-15 82 views
0

我在Tornado中有一个处理程序,它有一个get()和post()方法。 get方法获取一些数据库信息并使用html进行呈现。 post方法用于加载页面后的ajax调用,并且需要使用get()方法收集的DB数据。在Python的Tornado框架中,实例变量和类变量混淆

我的问题是,如果我将get()和post()之间需要共享的变量设置为实例变量(即在get()方法中设置self.variable =“foobar”),那么post )方法不能识别那些实例变量存在。我发现的唯一解决方法是,如果我将这些变量设置为全局类变量,并在get()中使用MyHandler.variable =“foobar”重置它们。但这似乎是一个骇人听闻的解决方案。

作品:

class AdminHandler(BaseHandler): 

file_count = 0 
mw_count = 0 
bw_count = 0 
unknown_count = 0 
files = [] 
origins = {} 
file_dicts = [] 

def get(self): 
    AdminHandler.file_count = 0 
    AdminHandler.mw_count = 0 
    AdminHandler.bw_count = 0 
    AdminHandler.unknown_count = 0 
    AdminHandler.files = [] 
    AdminHandler.origins = {} 
    AdminHandler.file_dicts = [] 

    .... 

def post(self): 
    (access class variables) 
    .... 

不起作用:

class AdminHandler(BaseHandler): 

def get(self): 
    self.file_count = 0 
    self.mw_count = 0 
    self.bw_count = 0 
    self.unknown_count = 0 
    self.files = [] 
    self.origins = {} 
    self.file_dicts = [] 

    .... 

def post(self): 
    (access instance variables) 
    .... 
+0

对于每个请求,您都会得到一个新的AdminHandler实例 - 因此,在调用get和post函数之间不会共享任何状态,就像两次连续调用get之间不会共享状态一样。 。 – dano

+0

HTTP应该是无状态的。不要在该类上存储GET数据; POST请求完全独立且独立,您收到的GET和POST请求的顺序不一定与一个客户端相关。 –

+0

在POST中进行*相同的数据库查询*。 –

回答

0

如果要存储的信息必须是可用于所有的请求(不是每个用户..)然后就可以实现类那会为你保存这些信息。例如:

from threading import Lock 
class MyDataStore: 

    _instance = None 
    _lock = Lock() 

    @classmethod 
    def instance(cls): 
     with cls._lock: 
      if cls._instance is None: 
       cls._instance = MyDataStore() 
      return cls._instance 

    def store_data(self, file_count, mw_count, ...): 
     self.file_count = file_count 
     self.mw_count = mw_count 

     ....... 
MyDataStore.instance().store_data(file_count, mw_count) 

以这种方式,您将只有一个商店类的实例将为您保存信息。

取代store_data方法,您可以实现自己的方法来处理您所需的信息(可以使用init方法)。你也可以添加一个方法,告诉你数据是否已经存在或是否需要更新。

如果您需要为每个用户单独保存数据,您可以按照之前编写的方式创建单独的类UserDataStore,但不使用锁和实例()方法。例如:

class UserDataStore: 

    def __init__(self, user_id, file_count, mw_count, ....): 
     self.user_id = user_id 
     self.file_count = file_count 
     self.mw_count = mw_count 

     ......... 

以这种方式,您将为每个用户拥有不同的实例。

您可以使用的另一个解决方案是使用Redis来存储您的数据。只需将数据字典存储在密钥“db_data”下并随时检索。 (如果用户的数据可以使用键'db_data:')。