现有属性引起的AttributeError
AttributeError caused by existing attribute
我 有时 在我的 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'>
>>>
tl;dr: 尝试在应用程序启动位置导入 pylibmc,例如 uwsgi
或 manage.py
文件。
我的 猜测 是在 PyLibMCCache.__init__
内的请求线程中导入 pylibmc
时出现多线程问题,而不是在应用程序启动时。 (IMO Django 在那里进行导入,因为并非所有 Django 安装都使用 pylibmc
,因此他们不应该将其作为依赖项强加到每个应用程序上)
虽然 我对 import
ing 工作原理的内部结构不够熟悉,但我怀疑会发生如下情况
- 线程 #1 尝试导入
pylibmc
- thread #1 在
sys.modules
中为 pylibmc
放置了一个占位符
- 线程 #2 尝试导入
pylibmc
->
AttributeError
被引发
- 线程 #1 已完成更新
sys.modules
,现在 pylibmc.NotFound
可用
一般来说,Python 似乎 discourage runtime loading of modules 而不是启动时加载。
重点是我的
Note: For projects where startup time is critical, this class [importlib.util.LazyLoader
] allows for potentially minimizing the cost of loading a module if it is never used. For projects where startup time is not essential then use of this class is heavily discouraged due to error messages created during loading being postponed and thus occurring out of context.
我 有时 在我的 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'>
>>>
tl;dr: 尝试在应用程序启动位置导入 pylibmc,例如 uwsgi
或 manage.py
文件。
我的 猜测 是在 PyLibMCCache.__init__
内的请求线程中导入 pylibmc
时出现多线程问题,而不是在应用程序启动时。 (IMO Django 在那里进行导入,因为并非所有 Django 安装都使用 pylibmc
,因此他们不应该将其作为依赖项强加到每个应用程序上)
虽然 我对 import
ing 工作原理的内部结构不够熟悉,但我怀疑会发生如下情况
- 线程 #1 尝试导入
pylibmc
- thread #1 在
sys.modules
中为pylibmc
放置了一个占位符
- 线程 #2 尝试导入
pylibmc
->
AttributeError
被引发 - 线程 #1 已完成更新
sys.modules
,现在pylibmc.NotFound
可用
一般来说,Python 似乎 discourage runtime loading of modules 而不是启动时加载。
重点是我的
Note: For projects where startup time is critical, this class [
importlib.util.LazyLoader
] allows for potentially minimizing the cost of loading a module if it is never used. For projects where startup time is not essential then use of this class is heavily discouraged due to error messages created during loading being postponed and thus occurring out of context.