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实现端口复用实例代码
Jul 03 Python
浅析Python多线程下的变量问题
Apr 28 Python
如何准确判断请求是搜索引擎爬虫(蜘蛛)发出的请求
Oct 13 Python
Python 稀疏矩阵-sparse 存储和转换
May 27 Python
python判断数字是否是超级素数幂
Sep 27 Python
python读取有密码的zip压缩文件实例
Feb 08 Python
用python写测试数据文件过程解析
Sep 25 Python
python 正则表达式贪婪模式与非贪婪模式原理、用法实例分析
Oct 14 Python
基于nexus3配置Python仓库过程详解
Jun 15 Python
python 抓取知乎指定回答下视频的方法
Jul 09 Python
python中绕过反爬虫的方法总结
Nov 25 Python
python使用Windows的wmic命令监控文件运行状况,如有异常发送邮件报警
Jan 30 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面向对象之标识对象
2017/06/27 PHP
php的常量和变量实例详解
2017/06/27 PHP
详解PHP使用Redis存储session时的一个Warning定位
2017/07/05 PHP
ASP SQL防注入的方法
2008/12/25 Javascript
JavaScript CSS修改学习第六章 拖拽
2010/02/19 Javascript
JavaScript内核之基本概念
2011/10/21 Javascript
Javascript中的默认参数详解
2014/10/22 Javascript
详谈JavaScript内存泄漏
2014/11/14 Javascript
JavaScript电子时钟倒计时第二款
2016/01/10 Javascript
JS实现title标题栏文字不间断滚动显示效果
2016/09/07 Javascript
浅谈jquery上下滑动的注意事项
2016/10/13 Javascript
js如何判断是否在iframe中及防止网页被别站用iframe嵌套
2017/01/11 Javascript
Angularjs自定义指令实现分页插件(DEMO)
2017/09/16 Javascript
JavaScript实现计数器基础方法
2017/10/10 Javascript
浅谈如何使用 webpack 优化资源
2017/10/20 Javascript
Vue框架之goods组件开发详解
2018/01/25 Javascript
解决VUEX兼容IE上的报错问题
2018/03/01 Javascript
如何使用VuePress搭建一个类型element ui文档
2019/02/14 Javascript
react使用CSS实现react动画功能示例
2020/05/18 Javascript
如何构建一个Vue插件并生成npm包
2020/10/26 Javascript
[51:17]Mski vs VGJ.S Supermajor小组赛C组 BO3 第三场 6.3
2018/06/04 DOTA
python实现汉诺塔递归算法经典案例
2021/03/01 Python
用Python实现读写锁的示例代码
2018/11/05 Python
Python使用pyshp库读取shapefile信息的方法
2018/12/29 Python
Python集合操作方法详解
2020/02/09 Python
python中安装django模块的方法
2020/03/12 Python
超全Python图像处理讲解(多模块实现)
2020/04/13 Python
澳大利亚便宜的家庭购物网站:CrazySales
2018/02/06 全球购物
美国亚马逊旗下男装网站:East Dane(支持中文)
2019/09/25 全球购物
简述安装Slackware Linux系统的过程
2012/01/12 面试题
基层干部群众路线教育实践活动个人对照检查材料
2014/09/23 职场文书
教学督导岗位职责
2015/04/10 职场文书
2015年社区统计工作总结
2015/04/21 职场文书
周恩来的四个昼夜观后感
2015/06/03 职场文书
解决go在函数退出后子协程的退出问题
2021/04/30 Golang
详解Go语言运用广度优先搜索走迷宫
2021/06/23 Python