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:uwsgiまたはmanage.pyファイルなど、アプリケーションの起動場所で pylibmc をインポートしてみてください。

私の推測では、アプリケーションの起動時ではなく、pylibmc内部のリクエスト スレッドにインポートする際のマルチスレッドの問題であると思われます。(すべての Django インストールが を使用するわけではないため、IMO Django はそこでインポートを行います。したがって、依存関係として各アプリに強制するべきではありません)PyLibMCCache.__init__pylibmc

私はimportingがどのように機能するかの内部に十分に精通していませんが、何が起こるかは以下のようなものだと思います

  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 に答える