只加载一次pickle list - Django \ Python

时间:2011-02-08 12:46:04

标签: python django django-views pickle

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

加载大约需要1-1.5秒。

将这个列表用于我的视图有什么好办法,但只对文件进行一次修补?

编辑:

会导入settings.py被认为是好吗?


有什么想法吗?

3 个答案:

答案 0 :(得分:2)

我会编写一个python模块 - 一个带有init方法的单例类,它将pickle数据读入python对象,然后是获取信息所需的“get”方法。

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

答案 1 :(得分:2)

你如何做到

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

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

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

如何运作

Python中的模块仅为每个Python进程导入一次。如果多次使用import,它将仅返回对已导入模块的引用。因此,如果你有一个运行带有4个worker的mod_wsgi的Apache,get_my_data()只会被调用4次,因为只有4个Python进程在运行。请记住,工人可能会死亡,被重新加载,被杀等等。但它应该将get_my_data()的呼叫保持在最低限度。

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

关于语法:

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

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

为什么你可能不想这样做

  1. 如果您为网站的每个页面加载一些需要2秒钟为每个请求生成的内容,那么就会出错。您可能想重新考虑您的架构。
  2. 如果数据不是为了返回值,而是在用户操作后运行进程,那么使用Celery等工具运行异步函数可能会更好。
  3. get_my_data()模块无论如何都会缓存正则表达式,因此您可能不再需要编译它们。其他数据可能表示为原始数据。将所有这些作为字符串和其他基元存储在缓存后端(例如memcached或redis)中,它将变得更加清晰。 另外,如果一个Python进程更新缓存,那么其他人将会意识到它。他们不会使用上面的代码片段。
  4. 关于settings.py

    的最后一句话

    您不应该输入settings.py文件:

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

答案 2 :(得分:1)

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

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