1. 程式人生 > >python裝飾器(新年第一寫)

python裝飾器(新年第一寫)

祭奠碌碌無為的2018,想想其實也不算碌碌無為,至少我還搞懂了裝飾器,寫了一堆有用沒用的玩意

原來覺得裝飾器挺難的,直到2018年的最後幾天,突然就明白了,難道這就是傳說中的開天聰麼

言歸正傳,之所以覺得裝飾器難,是因為這東西不按套路出牌,希望大家看完我寫的也能在新的一年裡有所收貨吧

先說下要實現的功能,寫一個裝飾器,讓裝飾器可以把時間加到日誌的行首,例如

20190101 000001 write log first values

20190101 000001使用裝飾器寫入,而write log first values使用函式寫入

首先寫一個正常的寫入日誌的函式

def write_log(values):
  return values

函式介紹:一段簡單的函式,只是將values寫入並返回,看起來像脫了褲子放屁,先這樣,後面呼叫裝飾器的時候是需要用這個函式的

測試下函式

write_values = 'write log first values'

result = write_log(write_values)

print result

正常寫入,檢視檔案內容

write log first values

因為需要寫入時間,所以還需要一個寫入處理時間的函式

import time
def
now_time(): local_time = time.localtime(time.time()) time_format
= '%Y%m%d %H%M%S' time_result = time.strftime(time_format,local_time) return time_result

函式介紹:將當前日期轉換成需要的日期格式

測試下函式

now = now_time()

print now

結果是

20190101 013041

日期正常,再來寫個裝飾器函式

敲小黑板,這裡是重點,重點,重點,重要的事情說三遍---------------------------------------------------------

def add_time_line_start(func1):
  
def insert_time(): now = now_time() return now +' ' + func1() return insert_time

函式介紹:首先定義了一個裝飾器函式add_time_line_start,傳入了一個引數是func1,之所以說裝飾器不按套路出牌這裡是詭異地方1,這裡傳入的func1引數其實是個函式,並不是我們平常認為的一個字串或者list什麼的,接下來是裝飾器裡面的insert_time函式,這個函式是裝飾器的功能函式,也就是裝飾器需要實現的功能在這裡實現。說一下insert_time的功能,獲取到當前時間,並且把當前時間拼到傳入的函式前面返回。最後最外層是返回inser_time函式,即將拼接好的結果返回

測試下函式,這裡需要全部的函數了,現在把全部函式都放進來,存成一個檔案叫zsq.py

#!/usr/bin/python
# coding: UTF-8

import time

# 日期時間函式
def now_time():
  local_time = time.localtime(time.time())
  time_format = '%Y%m%d %H%M%S'
  time_result = time.strftime(time_format,local_time)
  return time_result

# 裝飾器函式
def add_time_line_start():
  def insert_time():
    now = now_time()
    return now + ' ' + func1()
  return insert_time

#呼叫裝飾器
@add_time_line_start

#看起來沒什麼用的函式
def write_log(values):
  return values

write_values = 'write log first values'
result = write_log(write_values)
print result

這裡看到了呼叫裝飾器是使用的@方法,@add_time_line_start,說下我的理解,這個其實就是等於平常函式的add_time_line_start(write_log())這種方法,這也就是裝飾器不按套路出牌這裡是詭異地方2

測試下

python zsq.py

結果是

Traceback (most recent call last):
  File "zshq1.py", line 28, in <module>
    print write_log(write_values)
TypeError: insert_time() takes no arguments (1 given)

臥槽,報錯了,為什麼,這也是個坑,為這個真是研究了半天,因為傳入裝飾器的函式有傳參,所以insert_time()需要同步傳參,但是傳什麼呢,這裡有個特殊用法,在函式傳參的地方寫上self就好了,下面是改正後的結果def insert_time():   return now + ' ' + func1()注意這兩個地方

 

#!/usr/bin/python
# coding: UTF-8

import time

# 日期時間函式
def now_time():
  local_time = time.localtime(time.time())
  time_format = '%Y%m%d %H%M%S'
  time_result = time.strftime(time_format,local_time)
  return time_result

# 裝飾器函式
def add_time_line_start(func1):
  def insert_time(self):
    now = now_time()
    return now + ' ' + func1(self)
  return insert_time

#呼叫裝飾器
@add_time_line_start

#看起來沒什麼用的函式
def write_log(values):
  return values

def write_log1(values):
  return values

write_values = 'write log first values'
result = write_log1(write_values)
print result

 

再測試下

python zsq.py

結果是

20190101 022028 write log first values

這次OK了,安心睡覺咯,留個疑問吧,就是這個裝飾器是不是對下面所有的函式都會複用呢,答案當然是自己動手試試咯