前一段时间为公司的业务写了一个非常轻量级的监控平台,最近抽出空来整理一下思路。首先从一个小 trick 开始吧。

scrapy 中的 item pipeline

我写的监控平台的 pipeline 机制主要模仿了 scrapy 中的 item pipeline。 在 scrapy 的配置文件中,pipeline 的配置表示方式是这样的:

1
2
3
4
ITEM_PIPELINES = {
'myproject.pipelines.FirstPipeline': 300,
'myproject.pipelines.SecondPipeline': 800,
}

ITEM_PIPELINES作为一个字典,key就是处理类的路径,value值的大小则代表了该 pipeline 的优先级。

我们的监控平台远没有 scrapy 这么复杂,因此就只需要一个列表,根据列表顺序依次执行函数就可以了。于是问题来了。(学挖掘机哪家强?)我们如何像 scrapy 一样通过字符串表示的路径来读取出相应的类或者函数呢?

importlab 的使用

其实非常简单,我们只需要使用importlib来引入对应的包就可以了。如果需要返回具体的执行函数,就利用getattr。具体代码示例如下:

1
2
3
4
5
6
7
8
def import_attribute(name):
"""Return an attribute from a dotted path name (e.g. "path.to.func")."""
module_name, attribute = name.rsplit('.', 1)
module = importlib.import_module(module_name)
return getattr(module, attribute)

func = import_attribute('monitor_platform.src.pipelines.common_pipeline.send_mail')
func()

在主线程中,调用import_attribute,首先.rsplit将包名与属性名分离,然后通过importlib.import_module引入包,最后通过getattr获取到该属性,此时获取到的func就是我们希望执行的函数了。只要提供一个 pipeline 的列表,就可以依次引入,顺序执行。就是这么简单。