python log函数_python要点-装饰器
大家有沒有碰到過這種需求,擴展公司的歷史項目,對功能進行擴展?拿到歷史項目看源碼的時候是不是頭特別大,難上加難的是還要對其進行修改!!!今天要講的是python中的重要功能-裝飾器,其對滿足前述的實現就提供了很友好的支持。
那么什么是裝飾器,裝飾器(Decorators)是 Python 的一個重要部分。簡單地說:他們是修改其他函數的功能的函數。他們有助于讓我們的代碼更簡短,代碼修改起來也更容易,也更Pythonic(Python范兒)。大多數初學者不知道在哪兒使用它們,所以我將要分享下,哪些區域里裝飾器可以讓你的代碼更簡潔。 首先,讓我們討論下如何寫你自己的裝飾器。
預定場景:大家在很多時候實現功能的時候可能都需要實現對函數執行時間的統計,總的來說實現對函數執行時間的記時是很簡單的,就是執行前執行后的時間差。那么更重要的是什么,就是如何讓實現簡單功能的函數能夠更好的嵌入到我們的整個功能函數里,并且能夠實現對其很好的調用、或者是更好的滿足優秀的設計思想。
就上面的需求來說,實現的方式有很多:
1、在每個需要記錄時間的函數里都寫上時間計算的語句。
2、寫一個計算時間的方法,在需要的地方進行調用。都是簡單的方法,但如果需求量大了之后,從定義上、設計模式思想上來說,前兩種方法,可能就不是那么美觀了。最直觀的就是,你可能需要寫大量的重復語句或者是函數調用。
所以我們提倡使用今天要給大家講的-python裝飾器,裝飾器的功能在前文也說到了,就是支持更友好的修改擴展歷史功能以及寫法上更pythonic。我們就以上述需求為例實現,上代碼:
(1)函數裝飾器
# coding:utf-8 import timedef decorator_time(func):def wrapper(*args, **kwargs):start_time = time.time()func(*args, **kwargs)end_time = time.time()use_time = end_time - start_timeprint("函數運行花費時間:{}".format(use_time))return funcreturn wrapper@decorator_time def add(a, b):time.sleep(1)print("a+b={}".format(a + b))add(1, 3)在上述代碼中,decorator_time就是一個實現函數運行花費時間計算的裝飾器,加入我們的原始函數功能就是實現加法的函數,如果我們要通過修改原函數代碼實現,當然也可以,但是就破壞了原始代碼的結構性,通過上面代碼所使用的方法,是不是就簡單多了,只需要在原函數上面加上@decorator_time即可,@是python中的語法糖,一種使用形式而已。
當然功能函數很多時候都是需要傳入參數的,裝飾器也是一樣的,例如簡單的日志功能,可能包含簡單的等級信息,例如信息、警告、危險、錯誤等。那我們如何實現帶參數的裝飾器,如下:
# coding:utf-8 import timedef loginfo(level=1):def decorator_log(func):def wrapper(*args, **kwargs):if level == 1:print("這是一條顯示信息。")if level == 2:print("這是一條警告信息。")if level == 3:print("這是一條錯誤信息。")func(*args, **kwargs)return funcreturn wrapperreturn decorator_log@loginfo(level=2) def add(a, b):print("a+b={}".format(a + b))add(1, 3)以上就是函數裝飾器的簡單實現以及運用。
(2)類裝飾器
同樣適用與上述場景,如果我們實現了多個函數裝飾器,我們要同時使用多個裝飾器的時候,怎么用呢,首先一個函數是可以同時使用多個裝飾器的,依次將裝飾器通過@寫在上面即可。只不過,我們還可以用繼承的的方式實現裝飾器,這樣,新寫的裝飾器就能包含歷史的功能。例如,我們有一個寫日志的裝飾器,現在我們需要增加的就是如果日志等級較高,包含有錯誤等信息,希望裝飾器可以將其通過發郵件的方法通知管理員。
那這個時候我們只需要新寫一個繼承原裝飾器的新裝飾器即可,只不過新的裝飾器需要寫入郵件發送的函數。類裝飾器是通過類的__call__方法實現的。源碼如下:
class logit():def __init__(self, logfile='out.log'):self.logfile = logfiledef __call__(self, func):def wrapped_function(*args, **kwargs):log_string = func.__name__ + " was called"print(log_string)# 打開logfile并寫入with open(self.logfile, 'a') as opened_file:# 現在將日志打到指定的文件opened_file.write(log_string + 'n')# 現在,發送一個通知self.notify()return func(*args, **kwargs)return wrapped_functiondef notify(self):# logit只打日志,不做別的passclass email_logit(logit):''' 一個logit的實現版本,可以在函數調用時發送email給管理員 ''' def __init__(self, email='admin@myproject.com', *args, **kwargs): self.email = email super(email_logit, self).__init__(*args, **kwargs) def notify(self): # 發送一封email到self.email # 這里就不做實現了 pass使用方法和函數裝飾器一樣,只需要在原功能函數上面添加@email_logit即可。
裝飾器主要適用于插入日志、性能測試、事務處理、緩存、權限校驗等場景
總結
以上是生活随笔為你收集整理的python log函数_python要点-装饰器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c++ 文件读写_Java文件读写的常用
- 下一篇: bat射击游戏代码_这张图打开就是3D射