Python中装饰器的一个妙用


Posted in Python onFebruary 08, 2015

好吧,我知道是大半夜……,但我还是觉得赶紧花上半个小时,把这最新的想法分享出来是值得的~直接进入正题~

我们来模拟一个场景,需要你去抓去一个页面,然后这个页面有好多url也要分别去抓取,而进入这些子url后,还有数据要抓取。简单点,我们就按照三层来看,那我们的代码就是如下:

def func_top(url):

    data_dict= {}

 

    #在页面上获取到子url

    sub_urls = xxxx

 

    data_list = []

    for it in sub_urls:

        data_list.append(func_sub(it))

 

    data_dict[\'data\'] = data_list

 

    return data_dict

 

def func_sub(url):

    data_dict= {}

 

    #在页面上获取到子url

    bottom_urls = xxxx

 

    data_list = []

    for it in bottom_urls:

        data_list.append(func_bottom(it))

 

    data_dict[\'data\'] = data_list

 

    return data_dict

 

def func_bottom(url):

    #获取数据

    data = xxxx

    return data

func_top是上层页面的处理函数,func_sub是子页面的处理函数,func_bottom是最深层页面的处理函数,func_top会在取到子页面url后遍历调用func_sub,func_sub也是同样。

如果正常情况下,这样确实已经满足需求了,但是偏偏这个你要抓取的网站可能极不稳定,经常链接不上,导致数据拿不到。

于是这个时候你有两个选择:

1.遇到错误就停止,之后重新从断掉的位置开始重新跑
2.遇到错误继续,但是要在之后重新跑一遍,这个时候已经有的数据不希望再去网站拉一次,而只去拉没有取到的数据

对第一种方案基本无法实现,因为如果别人网站的url调整顺序,那么你记录的位置就无效了。那么只有第二种方案,说白了,就是要把已经拿到的数据cache下来,等需要的时候,直接从cache里面取。

OK,目标已经有了,怎么实现呢?

如果是在C++中的,这是个很麻烦的事情,而且写出来的代码必定丑陋无比,然而庆幸的是,我们用的是python,而python对函数有装饰器。

所以实现方案也就有了:

定义一个装饰器,如果之前取到数据,就直接取cache的数据;如果之前没有取到,那么就从网站拉取,并且存入cache中.

代码如下:

def get_dump_data(dir_name, url):

    m = hashlib.md5(url)

    filename = m.hexdigest()

    full_file_name = \'dumps/%s/%s\' % (dir_name,filename)

 

    if os.path.isfile(full_file_name):

        return eval(file(full_file_name,\'r\').read())

    else:

        return None

 

 

def set_dump_data(dir_name, url, data):

    if not os.path.isdir(\'dumps/\'+dir_name):

        os.makedirs(\'dumps/\'+dir_name)

 

    m = hashlib.md5(url)

    filename = m.hexdigest()

    full_file_name = \'dumps/%s/%s\' % (dir_name,filename)

 

    f = file(full_file_name, \'w+\')

    f.write(repr(data))

    f.close()

 

 

def deco_dump_data(func):

    def func_wrapper(url):

        data = get_dump_data(func.__name__,url)

        if data is not None:

            return data

 

        data = func(url)

        if data is not None:

            set_dump_data(func.__name__,url,data)

        return data

 

    return func_wrapper

然后,我们只需要在每个func_top,func_sub,func_bottom都加上deco_dump_data这个装饰器即可~~

搞定!这样做最大的好处在于,因为top,sub,bottom,每一层都会dump数据,所以比如某个sub层数据dump之后,是根本不会走到他所对应的bottom层的,减少了大量的开销!

OK,就这样~ 人生苦短,我用python!

Python 相关文章推荐
python计数排序和基数排序算法实例
Apr 25 Python
Python查找函数f(x)=0根的解决方法
May 07 Python
实现python版本的按任意键继续/退出
Sep 26 Python
Python 内置函数complex详解
Oct 23 Python
Python快速从注释生成文档的方法
Dec 26 Python
Python连接phoenix的方法示例
Sep 29 Python
浅谈python日志的配置文件路径问题
Apr 28 Python
virtualenv 指定 python 解释器的版本方法
Oct 25 Python
Python批处理更改文件名os.rename的方法
Oct 26 Python
Django中密码的加密、验密、解密操作
Dec 19 Python
python如何提取英语pdf内容并翻译
Mar 03 Python
Python操作Excel工作簿的示例代码(\*.xlsx)
Mar 23 Python
Python中使用HTMLParser解析html实例
Feb 08 #Python
Pyhton中防止SQL注入的方法
Feb 05 #Python
Windows系统下安装Python的SSH模块教程
Feb 05 #Python
Python 冒泡,选择,插入排序使用实例
Feb 05 #Python
Python中使用Flask、MongoDB搭建简易图片服务器
Feb 04 #Python
Python os模块中的isfile()和isdir()函数均返回false问题解决方法
Feb 04 #Python
Python中使用socket发送HTTP请求数据接收不完整问题解决方法
Feb 04 #Python
You might like
PHP小技巧搜集,每个PHPer都来露一手
2007/01/02 PHP
PHP下通过exec获得计算机的唯一标识[CPU,网卡 MAC地址]
2011/06/09 PHP
php学习笔记之面向对象编程
2012/12/29 PHP
Yii框架创建cronjob定时任务的方法分析
2017/05/23 PHP
php设计模式之策略模式实例分析【星际争霸游戏案例】
2020/03/26 PHP
THINKPHP5分页数据对象处理过程解析
2020/10/28 PHP
JavaScript入门教程(5) js Screen屏幕对象
2009/01/31 Javascript
functional继承模式 摘自javascript:the good parts
2011/06/20 Javascript
说说JSON和JSONP 也许你会豁然开朗
2012/09/02 Javascript
如何将一个String和多个String值进行比较思路分析
2013/04/22 Javascript
AngularJS基础 ng-include 指令示例讲解
2016/08/01 Javascript
jQuery实现联动下拉列表查询框
2017/01/04 Javascript
Angular的$http的ajax的请求操作(推荐)
2017/01/10 Javascript
Ext JS 实现建议词模糊动态搜索功能
2017/05/13 Javascript
Vue中的Props(不可变状态)
2018/09/29 Javascript
JavaScript对象拷贝与赋值操作实例分析
2018/12/10 Javascript
优雅的elementUI table单元格可编辑实现方法详解
2018/12/23 Javascript
原生javascript实现连连看游戏
2019/01/03 Javascript
记一次vue去除#问题处理经过小结
2019/01/24 Javascript
微信小程序实现签字功能
2019/12/23 Javascript
js判断密码强度的方法
2020/03/18 Javascript
PyTorch学习笔记之回归实战
2018/05/28 Python
使用python将图片按标签分入不同文件夹的方法
2018/12/08 Python
用Python和WordCloud绘制词云的实现方法(内附让字体清晰的秘笈)
2019/01/08 Python
如何基于python生成list的所有的子集
2019/11/11 Python
localStorage 设置过期时间的方法实现
2018/12/21 HTML / CSS
乌克兰移动电子产品和相关配件的在线商店:iTMag
2020/03/16 全球购物
某公司的.net工程师面试题笔试题
2013/11/22 面试题
专科应届生求职信
2013/11/24 职场文书
网上书店创业计划书
2014/01/12 职场文书
写求职信有什么意义
2014/02/17 职场文书
个人整改措施书面材料
2014/10/24 职场文书
2019新学期家长会工作计划
2019/08/21 职场文书
Redis的字符串是如何实现的
2021/10/24 Redis
Python按顺序遍历并读取文件夹中文件
2022/04/29 Python
python数字图像处理数据类型及颜色空间转换
2022/06/28 Python