王海波的个人网站

我要有能做我自己的自由,和敢做我自己的胆量!

插广告啦!联通秋季手机卡促销活动!

本人还是联通员工,所以帮公司宣传!^_^! 联通校园营销开始啦!200打一年,300打两年。头三个月每月7G流量,三月后,每个月4G流量。此外,每月还有200分钟免费语音。实在太优惠了!请大家广而告之。目前有尾号88,123,567等靓号,详情请点下面链接查看。

套餐详情,或者直接扫下方二维码选号购买!

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,所以才会执行该语句。这样就加载了配置文件。

--------EOF---------
本文微信分享/扫码阅读

文章评论
暂时无评论,快在文章下面留言吧。
${comment.author.fields.name}} ${comment.create_time}}
${comment.content}} 
${reply.author.fields.name}} @ ${reply.reply_to.fields.name}} ${reply.create_time}}
${reply.content}}