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搭建简易服务器分析与实现
Dec 15 Python
Python语言实现获取主机名根据端口杀死进程
Mar 31 Python
Python微信库:itchat的用法详解
Aug 14 Python
Python下载网络小说实例代码
Feb 03 Python
python中partial()基础用法说明
Dec 30 Python
python遍历文件目录、批量处理同类文件
Aug 31 Python
python3 webp转gif格式的实现示例
Dec 10 Python
下载与当前Chrome对应的chromedriver.exe(用于python+selenium)
Jan 14 Python
将tensorflow模型打包成PB文件及PB文件读取方式
Jan 23 Python
python实现引用其他路径包里面的模块
Mar 09 Python
vscode写python时的代码错误提醒和自动格式化的方法
May 07 Python
python爬虫之利用selenium模块自动登录CSDN
Apr 22 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
WINXP下apache+php4+mysql
2006/11/25 PHP
php上传apk后自动提取apk包信息的使用(示例下载)
2013/04/26 PHP
win7下memCache的安装过程(具体操作步骤)
2013/06/28 PHP
php微信公众平台开发之获取用户基本信息
2015/08/17 PHP
php生成复杂验证码(倾斜,正弦干扰线,黏贴,旋转)
2018/03/12 PHP
PHP中检查isset()和!empty()函数的必要性
2019/02/13 PHP
Javascript实例教程(19) 使用HoTMetal(7)
2006/12/23 Javascript
基于Jquery的简单图片切换效果
2011/01/06 Javascript
超轻量级的基于jquery的三级展开列表
2011/04/26 Javascript
JavaScript中的toLocaleLowerCase()方法使用详解
2015/06/06 Javascript
jquery实现简单实用的打分程序实例
2015/07/23 Javascript
JavaScript中数组的合并以及排序实现示例
2015/10/24 Javascript
基于javascript制作微博发布栏效果
2016/04/04 Javascript
js导出excel文件的简洁方法(推荐)
2016/11/02 Javascript
微信小程序Server端环境配置详解(SSL, Nginx HTTPS,TLS 1.2 升级)
2017/01/12 Javascript
JavaScript实现购物车基本功能
2017/07/21 Javascript
最全正则表达式总结:验证QQ号、手机号、Email、中文、邮编、身份证、IP地址等
2017/08/16 Javascript
Node.js自定义实现文件路由功能
2017/09/22 Javascript
基于vue实现分页效果
2017/11/06 Javascript
weui上传多图片,压缩,base64编码的示例代码
2020/06/22 Javascript
Python输出9*9乘法表的方法
2015/05/25 Python
用python与文件进行交互的方法
2018/03/01 Python
python 画三维图像 曲面图和散点图的示例
2018/12/29 Python
python2和python3实现在图片上加汉字的方法
2019/08/22 Python
python装饰器相当于函数的调用方式
2019/12/27 Python
PyQt5+Pycharm安装和配置图文教程详解
2020/03/24 Python
python topk()函数求最大和最小值实例
2020/04/02 Python
python 如何引入协程和原理分析
2020/11/30 Python
西北政法大学自主招生自荐信
2014/01/29 职场文书
幼儿园清明节活动总结
2014/07/04 职场文书
小学庆六一活动总结
2014/08/28 职场文书
公安机关党的群众路线教育实践活动剖析材料
2014/10/10 职场文书
2015年新学期寄语
2015/02/26 职场文书
应届生求职自荐信范文
2015/03/04 职场文书
安全教育日主题班会
2015/08/13 职场文书
2019年最新证婚词精选集!
2019/06/28 职场文书