2

当我的 django 应用程序尝试从缓存中获取或存储某些内容时,有时会出现以下错误:

    c = cache.get(pk)
  File "/opt/python3/lib/python3.4/site-packages/django/core/cache/__init__.py", line 131, in __getattr__
    return getattr(caches[DEFAULT_CACHE_ALIAS], name)
  File "/opt/python3/lib/python3.4/site-packages/django/core/cache/__init__.py", line 113, in __getitem__
    cache = _create_cache(alias)
  File "/opt/python3/lib/python3.4/site-packages/django/core/cache/__init__.py", line 88, in _create_cache
    return backend_cls(location, params)
  File "/opt/python3/lib/python3.4/site-packages/django/core/cache/backends/memcached.py", line 185, in __init__
    value_not_found_exception=pylibmc.NotFound)
AttributeError: 'module' object has no attribute 'NotFound'

但为什么?该模块具有该属性,并且大多数时候它都可以工作,没有同名的文件可以破坏这个,在哪里寻找这个原因?

>>> import pylibmc
>>> pylibmc.NotFound
<class '_pylibmc.NotFound'>
>>>
4

1 回答 1

1

tl;dr:尝试在应用程序启动位置导入 pylibmc,例如uwsgiormanage.py文件。

我的猜测pylibmc是,在内部的请求线程中导入PyLibMCCache.__init__而不是在应用程序启动时,这是一个多线程问题。(IMO Django 在那里进行导入,因为并非所有 Django 安装都使用pylibmc,因此他们不应该在每个应用程序上强制它作为依赖项)

虽然我对ing的工作原理还不够熟悉import,但我怀疑会发生如下情况

  1. 线程 #1 尝试导入pylibmc
  2. sys.modules线程 #1 在for中放置一个占位符pylibmc
  3. 线程 #2 尝试导入pylibmc -> 引发AttributeError
  4. 线程 #1 完成更新sys.modules,现在pylibmc.NotFound可用

一般来说,Python 似乎不鼓励在运行时加载模块,而不是在启动时加载。

重点是我的

注意:对于启动时间很关键的项目,此类 [ importlib.util.LazyLoader] 允许在从不使用模块的情况下最大限度地降低加载模块的成本。对于启动时间不是必需的项目,由于加载过程中创建的错误消息被推迟,因此严重不鼓励使用此类,因此会出现断章取义的情况。

于 2016-03-01T12:15:51.303 回答