在python的Tornado框架中,实例变量和类变量混淆



我在Tornado中有一个处理程序,它有一个get()和post()方法。get方法获取一些DB信息并将其与html一起呈现。post方法用于加载页面后的ajax调用,并且需要使用get()方法收集的DB数据。

我的问题是,如果我设置需要在get()和post()之间共享的变量作为实例变量(即设置self。变量= "foobar"(在get()方法中),则post()方法无法识别这些实例变量的存在。我发现的唯一解决方法是,如果我将这些变量设置为全局类变量并使用MyHandler重置它们。变量= get()中的"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)
    ....

如果您想要存储的信息必须对所有请求可用(而不是每个用户…),那么您可以实现一个类来为您保存这些信息。例如:

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,但不需要锁和instance()方法。例如:

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:')。

最新更新