celery加载配置文件
使用celery的时候,有句:app.config_from_object('dailyblog.conf:settings'),虽然我知道是用来导入配置文件的,但不知道如何实现的。因此,我是带着疑问来研究的,为什么这个method是可以根据字符串搜索配置文件?为什么还会有冒号":"? 研究代码走起。
def config_from_object(self, obj, silent=False, force=False): self._config_source = obj if force or self.configured: del(self.conf) return self.loader.config_from_object(obj, silent=silent)
该方法返回了一个Loader类的config_from_object:
def config_from_object(self, obj, silent=False):
if isinstance(obj, string_t):
try:
obj = self._smart_import(obj, imp=self.import_from_cwd)
except (ImportError, AttributeError):
if silent:
return False
raise
self._conf = force_mapping(obj)
return True
该类最关键的是两个语句:
obj = self._smart_import(obj, imp=self.import_from_cwd)
self._conf = force_mapping(obj)
第一句:
obj = self._smart_import(obj, imp=self.import_from_cwd)
看_smart_import源码:
def _smart_import(self, path, imp=None):
imp = self.import_module if imp is None else imp
if ':' in path:
# Path includes attribute so can just jump here.
# e.g. ``os.path:abspath``.
return symbol_by_name(path, imp=imp)
其实到这,就初步解释了我的第二个疑问,celery对“:”进行了处理,接下来看symbol_by_name的源码:
def symbol_by_name(name, aliases={}, imp=None, package=None,
sep='.', default=None, **kwargs):
sep = ':' if ':' in name else sep
module_name, _, cls_name = name.rpartition(sep)
if not module_name:
cls_name, module_name = None, package if package else cls_name
try:
try:
module = imp(module_name, package=package, **kwargs)
except ValueError as exc:
reraise(ValueError,
ValueError("Couldn't import {0!r}: {1}".format(name, exc)),
sys.exc_info()[2])
return getattr(module, cls_name) if cls_name else module
except (ImportError, AttributeError):
if default is None:
raise
return default
我删除了不是我关注的地方。看上面的代码,module_name, _, cls_name = name.rpartition(sep),这句话就将我们的参数分离成dailyblog.conf,settings。
然后他执行下面的语句:
module = imp(module_name, package=package, **kwargs)
这个imp是参数,是loader定义的method,原型:
def import_from_cwd(self, module, imp=None, package=None):
return import_from_cwd(
module,
self.import_module if imp is None else imp,
package=package,
)
***********************************
celery utils:
def import_from_cwd(module, imp=None, package=None):
"""Import module, but make sure it finds modules
located in the current directory.
Modules located in the current directory has
precedence over modules located in `sys.path`.
"""
if imp is None:
imp = importlib.import_module
with cwd_in_path():
return imp(module, package=package)
到目前为止,导入了当前目录的django.conf模块。然后再看上面symbol_name方法,该方法返回了return getattr(module, cls_name)。到这要明白,settings是一个对象,一个object,所以才会执行该语句。这样就加载了配置文件。
微信分享/微信扫码阅读