【问题标题】:Loading a pickled list just once - Django\Python只加载一次腌制列表 - Django\Python
【发布时间】:2011-02-08 12:46:03
【问题描述】:

我有一个包含已编译正则表达式列表和其他数据的 pickle 文件。

加载大约需要 1-1.5 秒。

有什么好的方法可以将此列表用于我的视图,但只对文件进行一次pickle 操作?

编辑:

导入到 settings.py 是否可以考虑?


有什么想法吗?

【问题讨论】:

  • 您必须一次将它们全部解开吗?你不能只解开你需要的那些吗?

标签: python django django-views pickle


【解决方案1】:

你怎么做

创建一个名为 cache.py 的模块,然后:

import cache
data = getattr(cache, 'data', '') or get_my_data()

这将仅通过服务器进程重新加载一次数据(这取决于您的设置、您的 Web 服务器以及您使用 WSGI 或 CGI 的位置)。在开发网络服务器(./manage.py runserver)中,每次修改文件时,缓存都会失效。

工作原理

每个 Python 进程只导入一次 Python 中的模块。如果您多次使用import,它只会返回对已导入模块的引用。因此,如果您有一个运行 mod_wsgi 且有 4 个工作人员的 Apache,get_my_data() 将仅被调用 4 次,因为只有 4 个 Python 进程在运行。请记住,工人可能会死亡、重新加载、被杀死等。但它应该尽量减少对 get_my_data() 的调用。

问题:如果一个进程修改了缓存数据,其他人不会知道。如果您的数据是静态的,那没关系。如果您需要使其保持最新状态,它将无法正常工作。对于这种方法或任何暗示使用单例的方法都是如此,除非您可以确保只有一个 Python 进程正在运行(您可以,但这不是此答案的目的)。

关于语法:

getattr(cache, 'data', '') 返回对象“缓存”的名称为“数据”的属性。如果不存在,则返回最后一个参数,这里是一个空字符串。

在 Python 中,or 是惰性的,如果可以返回,它将停止计算参数。在我们的例子中,如果 'data' 是缓存的一个属性,它将在布尔上下文中为 Trueor 将认为它已经完成了它的工作(因为它只需要一个值为 True 即可返回True) 并且将返回 True 而不运行 get_my_data()。但是,如果 'data' 不是缓存的属性,那么如果or 将评估一个空字符串,则将其视为False,然后运行get_my_data()

为什么你可能不想这样做

  1. 如果您为网站的每个页面加载需要 2 秒才能为每个请求生成的内容,则说明有问题。您可能需要重新考虑您的架构。
  2. 如果数据不是要返回值,而是在用户操作后运行一个进程,那么最好使用Celery 等工具运行异步函数。
  3. re 模块无论如何都会缓存正则表达式,因此您可能不再需要编译它们了。其他数据可能可以表示为原始数据。将所有这些作为字符串和其他原语存储在缓存后端(例如 memcached 或 redis)中,这样会更干净。 另外,如果一个 Python 进程更新了缓存,那么其他进程就会意识到这一点。他们不会使用上面的 sn-p。

关于 settings.py 的最后一句话

你不应该放在settings.py文件中:

  • 如果您对其进行硬编码,您的设置文件将无法读取,并且放入源代码控制工具会很烦人。
  • 你不能动态地把它放在这里,因为设置模块在 Django 中是只读的,除非你使用一些丑陋的 hack,否则会导致意想不到的问题。

【讨论】:

    【解决方案2】:

    我会编写一个 python 模块 - 一个带有 init 方法的单例类,该方法将腌制数据读入 python 对象,然后使用任何“获取”方法来获取信息。

    然后在您的 settings.py 中,您只需调用初始化方法。任何需要从中获取信息的东西都只是导入模块并使用 get 方法。

    【讨论】:

      【解决方案3】:

      你可以加载它,然后使用 django 缓存框架来存储它,这样它只会被加载一次。

      http://docs.djangoproject.com/en/dev/topics/cache/

      【讨论】:

      • 那根本没有帮助。缓存框架将再次腌制它来存储它。
      • 但是如果你使用像 memcached 这样的东西,你就会把它全部保存在内存中,这样会快得多。而且您还可以立即访问单个项目,而不必访问文件中相应位置的项目。
      猜你喜欢
      • 2015-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-12
      • 2011-09-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多