简体   繁体   English

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

[英]In python's Tornado framework, instance variable and class variable confusion

I have a handler in Tornado which has a get() and post() method. 我在Tornado中有一个具有get()和post()方法的处理程序。 The get method grabs some DB information and renders it with the html. get方法获取一些数据库信息,并使用html呈现它。 The post method is for ajax calls once the page is loaded and needs to use the DB data collected by the get() method. post方法用于页面加载后的ajax调用,并且需要使用由get()方法收集的DB数据。

My problem is that if I set the variables that need to be shared between get() and post() as instance variables (ie set self.variable = "foobar" in get() method), then the post() method does not recognize that those instance variables exist. 我的问题是,如果我将需要在get()和post()之间共享的变量设置为实例变量(即,在get()方法中设置self.variable =“ foobar”),则post()方法不会认识到那些实例变量存在。 The only workaround I've found is if I set those variables as global class variables and reset them with MyHandler.variable = "foobar" in get(). 我发现的唯一解决方法是,如果将这些变量设置为全局类变量,并在get()中使用MyHandler.variable =“ foobar”重置它们。 But this seems like a hackish solution. 但这似乎是一个棘手的解决方案。

Works: 作品:

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)
    ....

Does not work: 不起作用:

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)
    ....

If information that you want to store must be available for all requests (not per user..) then you can implement a class that will hold this information for you. 如果要存储的信息必须可用于所有请求(不是每个用户..),则可以实现一个类,该类将为您保存此信息。 For example: 例如:

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)

In this way you will have only one instance of your store class that will hold information for you. 这样,您将只有一个商店类实例可以为您保存信息。

Instead of store_data method you can implement your own method which will process your required information (You can do it by using init method). 代替store_data方法,您可以实现自己的方法,该方法将处理所需的信息(可以使用init方法来完成)。 Also you can add a method which will tell you if data already exists or is it required to update it. 您也可以添加一个方法,该方法将告诉您数据是否已经存在或是否需要更新。

In case you need to save data individually for each user you can create a separate class UserDataStore in way I wrote before but without lock and instance() methods. 如果需要为每个用户分别保存数据,则可以按照我之前编写的方式创建一个单独的类UserDataStore,但不使用lock和instance()方法。 For example: 例如:

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

      .........

In this way you will have different instances for each user. 这样,您将为每个用户拥有不同的实例。

Another solution that you can use is to use Redis to store your data. 您可以使用的另一种解决方案是使用Redis存储数据。 Just store your data dictionary under key 'db_data' and retrieve it whenever you want. 只需将数据字典存储在键“ db_data”下,并在需要时检索它即可。 (In case of data by users you can use key 'db_data:'). (如果用户提供数据,则可以使用键“ db_data:”)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM