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 相关文章推荐
详解Django中的form库的使用
Jul 18 Python
Python函数的周期性执行实现方法
Aug 13 Python
基于python的七种经典排序算法(推荐)
Dec 08 Python
Django组件cookie与session的具体使用
Jun 05 Python
django框架auth模块用法实例详解
Dec 10 Python
pytorch 中pad函数toch.nn.functional.pad()的用法
Jan 08 Python
Pytorch 实现sobel算子的卷积操作详解
Jan 10 Python
解决Python在导入文件时的FileNotFoundError问题
Apr 10 Python
Python requests.post方法中data与json参数区别详解
Apr 30 Python
Django nginx配置实现过程详解
Sep 10 Python
python 基于selenium实现鼠标拖拽功能
Dec 24 Python
Python Django 后台管理之后台模型属性详解
Apr 25 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中simplexml_load_string函数使用说明
2011/01/01 PHP
php入门学习知识点六 PHP文件的读写操作代码
2011/07/14 PHP
求PHP数组最大值,最小值的代码
2011/10/31 PHP
对淘宝URL中ID提取的PHP代码
2013/09/01 PHP
PHP常用编译参数中文说明
2014/09/27 PHP
UTF-8正则表达式如何匹配汉字
2015/08/03 PHP
jquery下组织javascript代码(js函数化)
2010/08/25 Javascript
javascript中的注释使用与注意事项小结
2011/09/20 Javascript
js用Date对象的setDate()函数对日期进行加减操作
2014/09/18 Javascript
Jquery实现图片预加载与延时加载的方法
2014/12/22 Javascript
JavaScript实现文本框中默认显示背景图片在获得焦点后消失的方法
2015/07/01 Javascript
js省市联动效果完整实例代码
2015/12/09 Javascript
JS中的forEach、$.each、map方法推荐
2016/04/05 Javascript
全面了解构造函数继承关键apply call
2016/07/26 Javascript
详解Angular 4.x Injector
2017/05/04 Javascript
vue.js基于v-for实现批量渲染 Json数组对象列表数据示例
2019/08/03 Javascript
LayUI数据接口返回实体封装的例子
2019/09/12 Javascript
分享8个JavaScript库可更好地处理本地存储
2020/10/12 Javascript
Python HTTP客户端自定义Cookie实现实例
2017/04/28 Python
Python 判断文件或目录是否存在的实例代码
2018/07/19 Python
Django网络框架之创建虚拟开发环境操作示例
2019/06/06 Python
Python 使用Opencv实现目标检测与识别的示例代码
2020/09/08 Python
CSS3实现千变万化的文字阴影text-shadow效果设计
2016/04/26 HTML / CSS
世嘉游戏英国官方商店:SEGA Shop UK
2019/09/20 全球购物
C&A巴西网上商店:时尚、衣服、手机和鞋子
2020/06/07 全球购物
初二政治教学反思
2014/01/12 职场文书
特色冷饮店创业计划书
2014/01/28 职场文书
小学生期末评语大全
2014/04/21 职场文书
森马旗舰店双十一营销方案
2014/09/29 职场文书
老公保证书怎么写
2015/02/26 职场文书
2015年教师自我评价范文
2015/03/04 职场文书
Django使用channels + websocket打造在线聊天室
2021/05/20 Python
用python修改excel表某一列内容的操作方法
2021/06/11 Python
把77A收信机改造成收音机
2022/04/05 无线电
golang操作rocketmq的示例代码
2022/04/06 Golang
科学家测试在太空中培育人造肉,用于未来太空旅行
2022/04/29 数码科技