当前位置:首页 > 技术 > 正文内容

[python]在场景中理解装饰器

admin56年前 (1970-01-01)技术1126
原来我也自己通过查资料,来学习python的装饰器,但是效果不好。因为没有接触过需要用到装饰器的场景,所以 一起的资料都只停留在纸面上,但是今天偶然看到了vimer的这篇文章:http://www.vimer.cn/2011/04/python%E8%A3%85%E9%A5%B0%E5%99%A8%E7%9A%84%E4%B8%80%E4%B8%AA%E5%A6%99%E7%94%A8.html 我们就根据这篇文章的思路来,在场景中理解python装饰器 其中的一个场景是:爬取数据的时候,目标网站,不稳定。爬虫在爬取数据的时候可能异常。 解决方案: 思路:把爬中的每个方法爬取的数据,都存在硬盘中,存储规则如下: file_path:/method_name/ file_name:MD5_number.txt 解释:MD5_number是通过方法名和传入的参数计算出来的唯一标识符(搜索一下MD5)这样做的好 处,不需要把数据爬下来之后才能判断是否爬过。 最后:如果方法爬取目标url的数据时异常,暂不执行该方法。最后多跑几次这个爬虫脚本就可以了!   该爬虫调用三个方法,设计一个通用的方法:根据每个方法的方法名和传入的参数通过MD5计算出唯一的标识符(MD5_numbe)。然后在file_path目录中查找文件名为MD5_numbe的文件,如果file_path中的没有这个文件,则按照存储规则存储数据。如果找到了,不存储到硬盘中,直接返回data,用于下一个方法。   ———————————— 场景结束 ++++++++++++ 在上面描述的这个场景中,修饰器用在什么地方? 对了!就是那个通用方法,就需要用修饰器来实现,为什么?一步步的来   python中一切东西都是对象。方法就可以做当作对象来传递!   1.什么是方法? 传入参数,然后对传入的参数进行一系列操作。 2.什么是高级方法 方法接受的参数是方法,仅此而已。 3.什么是闭包 当方法1里面有一个方法2,方法2调用的是方法1接收到的参数,最后结果返回方法2。提供这种实现的技术叫做闭包。   说到底修饰器就是一个方法,而传入的参数是方法,并在修饰器中对传入的方法进行一系列的操作(这里用到闭包)。从而实现了,在不修改原方法基础上,增加新的操作。比如上一个场景中的,检验有没有重复爬取数据。   爬中脚本中的代码片段 func_top是上层页面的处理函数,func_sub是子页面的处理函数,func_bottom是最深层页面的处理函数,func_top会在取到子页面url后遍历调用func_sub,func_sub也是同样。 1 def func_top(url): 2 data_dict= {} 3 4 #在页面上获取到子url 5 sub_urls = xxxx 6 7 data_list = [] 8 for it in sub_urls: 9 data_list.append(func_sub(it)) 10 11 data_dict['data'] = data_list 12 13 return data_dict 14 15 def func_sub(url): 16 data_dict= {} 17 18 #在页面上获取到子url 19 bottom_urls = xxxx 20 21 data_list = [] 22 for it in bottom_urls: 23 data_list.append(func_bottom(it)) 24 25 data_dict['data'] = data_list 26 27 return data_dict 28 29 def func_bottom(url): 30 #获取数据 31 data = xxxx 32 return data     所以实现方案也就有了:定义一个装饰器,如果之前取到数据,就直接取cache(file_path)的数据;如果之前没有取到,那么就从网站拉取,并且存入cache中. 1 import os 2 import hashlib 3 4 def deco_args_recent_cache(category='dumps'): 5 ''' 6 装饰器,返回最新cache的数据 7 ''' 8 def deco_recent_cache(func): 9 def func_wrapper(*args, **kargs): 10 sig = _mk_cache_sig(*args, **kargs) 11 data = _get_recent_cache(category, func.__name__, sig) 12 if data is not None: 13 return data 14 15 data = func(*args, **kargs) 16 if data is not None: 17 _set_recent_cache(category, func.__name__, sig, data) 18 return data 19 20 return func_wrapper 21 22 return deco_recent_cache 23 24 def _mk_cache_sig(*args, **kargs): 25 ''' 26 通过传入参数,生成唯一标识 27 ''' 28 src_data = repr(args) + repr(kargs) 29 m = hashlib.md5(src_data) 30 sig = m.hexdigest() 31 return sig 32 33 def _get_recent_cache(category, func_name, sig): 34 full_file_path = '%s/%s/%s' % (category, func_name, sig) 35 if os.path.isfile(full_file_path): 36 return eval(file(full_file_path,'r').read()) 37 else: 38 return None 39 40 def _set_recent_cache(category, func_name, sig, data): 41 full_dir_path = '%s/%s' % (category, func_name) 42 if not os.path.isdir(full_dir_path): 43 os.makedirs(full_dir_path) 44 45 full_file_path = '%s/%s/%s' % (category, func_name, sig) 46 f = file(full_file_path, 'w+') 47 f.write(repr(data)) 48 f.close() 最后,我们只需要在每个func_top,func_sub,func_bottom都加上deco_args_recent_cache这个装饰器即可~~   参考资料: 浅显理解闭包:https://serholiu.com/python-closures 修饰器:http://jnotes.googlecode.com/svn/trunk/Notes/NotesOnPythonLearning/Python_decorator.html

扫描二维码推送至手机访问。

版权声明:本文由冒牌码农发布,如需转载请注明出处。

本文链接:http://js.xxbyc.cn/post/51.html

分享给朋友:
返回列表

没有更早的文章了...

下一篇:宝塔专业版永久使用教程

“[python]在场景中理解装饰器” 的相关文章

lol段位级别图2023(英雄联盟的段位顺序图)

lol段位级别图2023(英雄联盟的段位顺序图)

北京时间1月12日,当你打开更新后的英雄联盟客户端时,预示着2023年新赛季已经开启。官方预计今天的更新将在中午12点前完成。就在此前,官方已经预告了今年排位赛的新变化:将分为两个小赛季。今天开始的新赛季将在6月举行。接下来是第二个迷你赛季...

五庄观副本攻略大全(五庄观副本五行阵法技巧)

五庄观副本攻略大全(五庄观副本五行阵法技巧)

复制简介:武庄观是经典的普通副本,每四天刷新一次。难度简单,回报一般。成绩要求:70分以上。份数:5-10人副本奖励:变身卡、宝石、多彩果实、动物决定等。记得在开始复制之前留点力气打开盒子。任务流程:点镇远大仙进入房子并打开箱子获得棍子(单...

steam顶级3a大作有哪些(24款公认好玩的3A游戏推荐)

steam顶级3a大作有哪些(24款公认好玩的3A游戏推荐)

有些游戏让我们着迷,并为此投入时间和精力;有些游戏会让我们哭,把我们带入其中;也有一些游戏会让我们又爱又恨,又喜又悲;这些都是我们独特的经历。本文中的这些3A游戏都是经过时间沉淀后才被玩家接受的。也可以称之为“此生必玩”!每个人心中都有自己...

平顶山副本奖励怎么样(平顶山副本5人刷攻略)

平顶山副本奖励怎么样(平顶山副本5人刷攻略)

文案简介:平顶山是经典的普通副本,四天刷新一次。难度简单,奖励高。是可以刷的副本之一。成绩要求:70分以上。份数:10人副本奖励:宝石、培育果实、珍珠、戒指礼服、宠物礼服、海鲜、彩色水果等。(查看什么是NPC奖励)任务流程:一、打败三个怪物...

原神阿莫斯之弓适合谁用

原神阿莫斯之弓适合谁用

补充问题:如何获得原神阿摩司之弓? [答案精选] 前神阿莫斯之弓是五星弓箭装备。它的主要属性可以提供一定的攻击力和百分比攻击力。同时特效可以带来普攻和瞄准攻击伤害,随着箭矢发射时间的增加,还可以提供更高的伤害(输出越远伤害越高)。所以建...

开放世界必玩3a大作推荐(这6款3A神作超适合杀时间!)

开放世界必玩3a大作推荐(这6款3A神作超适合杀时间!)

【/s2/】刺客信条奥德赛【/s2/】【/s2/】《刺客信条之信条奥德赛》是一款由育碧魁北克工作室开发、育碧发行的动作游戏。它于2018年10月5日发布,登陆PC、PS4和XboxOne平台。这部作品是《刺客信条》的第十一部作品。【/s2/...