原來我也自己通過查資料,來學習python的裝飾器,但是效果不好。因為沒有接觸過需要用到裝飾器的場景,所以
一起的資料都只停留在紙面上,但是今天偶然看到了vimer的這篇文章:
我們就根據這篇文章的思路來,在場景中理解python裝飾器
解決方案:
該爬蟲呼叫三個方法,設計乙個通用的方法:根據每個方法的方法名和傳入的引數通過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也是同樣。
1deffunc_top(url):
2 data_dict={}34
#在頁面上獲取到子url
5 sub_urls =***x
67 data_list =
8for it in
sub_urls:910
11 data_dict['
data
'] =data_list
1213
return
data_dict
1415
deffunc_sub(url):
16 data_dict={}
1718
#在頁面上獲取到子url
19 bottom_urls =***x
2021 data_list =
22for it in
bottom_urls:
2324
25 data_dict['
data
'] =data_list
2627
return
data_dict
2829
deffunc_bottom(url):30#
獲取資料
31 data =***x
32return data
所以實現方案也就有了:
定義乙個裝飾器,如果之前取到資料,就直接取cache(file_path)的資料;如果之前沒有取到,那麼就從**拉取,並且存入cache中.
1importos2
import
hashlib34
def deco_args_recent_cache(category='
dumps'):
5'''
6裝飾器,返回最新cache的資料
7'''
8def
deco_recent_cache(func):
910 sig = _mk_cache_sig(*args, **kargs)
11 data = _get_recent_cache(category, func.__name__
, sig)
12if data is
notnone:
13return
data
1415 data = func(*args, **kargs)
16if data is
notnone:
17 _set_recent_cache(category, func.__name__
, sig, data)
18return
data
1920
return
2122
return
deco_recent_cache
2324
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()
31return
sig32
33def
_get_recent_cache(category, func_name, sig):
34 full_file_path = '
%s/%s/%s
' %(category, func_name, sig)
35if
os.path.isfile(full_file_path):
36return eval(file(full_file_path,'r'
).read())
37else:38
return
none
3940
def_set_recent_cache(category, func_name, sig, data):
41 full_dir_path = '
%s/%s
' %(category, func_name)
42if
notos.path.isdir(full_dir_path):
43os.makedirs(full_dir_path)
4445 full_file_path = '
%s/%s/%s
' %(category, func_name, sig)
46 f = file(full_file_path, 'w+'
)47f.write(repr(data))
48 f.close()
最後,我們只需要在每個func_top,func_sub,func_bottom都加上deco_args_recent_cache這個裝飾器即可~~
python 在場景中理解裝飾器
原來我也自己通過查資料,來學習python的裝飾器,但是效果不好。因為沒有接觸過需要用到裝飾器的場景,所以 一起的資料都只停留在紙面上,但是今天偶然看到了vimer的這篇文章 我們就根據這篇文章的思路來,在場景中理解python裝飾器 解決方案 該爬蟲呼叫三個方法,設計乙個通用的方法 根據每個方法的...
簡單例子理解裝飾器
python中的裝飾器可謂極其神秘,雖然常聽到,使用裝飾器會讓 如虎添翼,網上更是用 外面加長褲來形象的解釋裝飾器,但我硬是看了很多次都不得要領。但我不能就這麼放棄啊,終於還是搞明白了點點,雖然不全面,但也算對裝飾器有了初步的了解吧。usr bin env python2 coding utf 8 ...
正確理解裝飾器
定義三個函式,w1函式內定義乙個內部函式,w1函式的返回值是乙個函式名 def w1 func definner print 驗證 func return inner deff1 print f1 deff2 print f2 test w1 f1 test 這相當於將f1函式傳遞給w1返回乙個函式...