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爬虫之抓取百度贴吧并存储到本地txt文件改进版
Nov 06 Python
linux 下实现python多版本安装实践
Nov 18 Python
python使用正则表达式替换匹配成功的组
Nov 17 Python
Python基于PyGraphics包实现图片截取功能的方法
Dec 21 Python
python实现外卖信息管理系统
Jan 11 Python
python队列queue模块详解
Apr 27 Python
anaconda中更改python版本的方法步骤
Jul 14 Python
python二维键值数组生成转json的例子
Dec 06 Python
pyinstaller 3.6版本通过pip安装失败的解决办法(推荐)
Jan 18 Python
Python编程快速上手——strip()函数的正则表达式实现方法分析
Feb 29 Python
Flask中sqlalchemy模块的实例用法
Aug 02 Python
Python读写锁实现实现代码解析
Nov 28 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
浅析Dos下运行php.exe,出现没有找到php_mbstring.dll 错误的解决方法
2013/06/29 PHP
PHP session文件独占锁引起阻塞问题解决方法
2015/05/12 PHP
php生成动态验证码gif图片
2015/10/19 PHP
调用WordPress函数统计文章访问量及PHP原生计数器的实现
2016/03/21 PHP
PHP+JavaScript实现无刷新上传图片
2017/02/21 PHP
PHP实现的多进程控制demo示例
2019/07/22 PHP
Laravel框架中队列和工作(Queues、Jobs)操作实例详解
2020/04/06 PHP
javascript 极速 隐藏/显示万行表格列只需 60毫秒
2009/03/28 Javascript
JS中处理与当前时间间隔的函数代码
2012/05/23 Javascript
jquery实现定时自动轮播特效
2015/12/10 Javascript
JavaScript中闭包的写法和作用详解
2016/06/29 Javascript
vue2.0 中#$emit,$on的使用详解
2017/06/07 Javascript
Vue学习笔记进阶篇之单元素过度
2017/07/19 Javascript
Vue.js中的图片引用路径的方式
2017/07/28 Javascript
从零开始学习搭建React脚手架项目
2018/08/23 Javascript
angular实现input输入监听的示例
2018/08/31 Javascript
详解JavaScript中new操作符的解析和实现
2020/09/04 Javascript
基于python的字节编译详解
2017/09/20 Python
Python实现的计数排序算法示例
2017/11/29 Python
对python list 遍历删除的正确方法详解
2018/06/29 Python
pandas重新生成索引的方法
2018/11/06 Python
Python操作Sonqube API获取检测结果并打印过程解析
2019/11/27 Python
Django操作session 的方法
2020/03/09 Python
pycharm实现在子类中添加一个父类没有的属性
2020/03/12 Python
python利用google翻译方法实例(翻译字幕文件)
2020/09/21 Python
改变 Python 中线程执行顺序的方法
2020/09/24 Python
python 获取计算机的网卡信息
2021/02/18 Python
钉钉企业内部H5微应用开发详解
2020/05/12 HTML / CSS
美国性感女装网站:bebe
2017/03/04 全球购物
Myprotein加拿大官网:欧洲第一的运动营养品牌
2018/01/06 全球购物
加拿大租车网站:Enterprise Rent-A-Car
2018/07/26 全球购物
澳大利亚个性化儿童礼品网站:Bright Star Kids
2019/06/14 全球购物
自荐信的五个重要部分
2013/10/29 职场文书
函授药学自我鉴定
2014/02/07 职场文书
教师职业道德事迹材料
2014/08/18 职场文书
公务员处分决定书
2015/06/25 职场文书