91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python裝飾器的使用方法有哪些

發布時間:2022-07-13 10:42:57 來源:億速云 閱讀:112 作者:iii 欄目:開發技術

這篇文章主要介紹了Python裝飾器的使用方法有哪些的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇Python裝飾器的使用方法有哪些文章都會有所收獲,下面我們一起來看看吧。

裝飾器的價值不言而喻,可以用來增強函數功能、簡化代碼、減少代碼冗余。

它的使用場景同樣很多,比較簡單的場景包含打印日志、統計運行時間,這類例子和用法網上已經很多了:

def time_dec(func):

  def wrapper(*arg):
      t = time.clock()
      res = func(*arg)
      print func.func_name, time.clock()-t
      return res

  return wrapper


@time_dec
def myFunction(n):
    ...

再進階一些的,可以用來校驗函數傳入參數類型、線程同步、單元測試等:

@parameters(
   (2, 4, 6),
   (5, 6, 11),
)
def test_add(a, b, expected):
    assert a + b == expected

目前可以用的裝飾器可以分為如下幾類:

  • 自定義

  • 第三方工具包

  • 內置

下面就分別來介紹一下。

自定義

關于自定義的裝飾器在前面已經提到了,我在開發過程中經常用到的就是日志打印、計時、數據校驗等場景,通過裝飾器可以提高代碼的簡潔性,避免重復造輪子。

除了這些基本的,也有一些比較實用的地方。

作為開發同學,肯定會遇到不同的運行環境:

  • 開發環境

  • 測試環境

  • 生產環境

有時候,我們期望一個函數在不同環境下執行不同的過程,產出不同的結果,做一些環境的隔離和差異化處理。

通過裝飾器就可以很好的解決:

production_servers = [...]

def production(func: Callable):
    def inner(*args, **kwargs):
        if gethostname() in production_servers:
            return func(*args, **kwargs)
        else:
            print('This host is not a production server, skipping function decorated with @production...')
    return inner

def development(func: Callable):
    def inner(*args, **kwargs):
        if gethostname() not in production_servers:
            return func(*args, **kwargs)
        else:
            print('This host is a production server, skipping function decorated with @development...')
    return inner

def sit(func: Callable):
    def inner(*args, **kwargs):
        print('Skipping function decorated with @sit...')
    return inner

@production
def foo():
    print('Running in production, touching databases!')

foo()

@development
def foo():
    print('Running in production, touching databases!')

foo()

@inactive
def foo():
    print('Running in production, touching databases!')

foo()

簡單的介紹一下這段代碼。

在這里,先是羅列了生產環境的服務列表,然后分別定義了生產、開發、測試環境的裝飾器,然后給同名的函數就可以配上對應的裝飾器。

在執行代碼的過程中,這段代碼會首先獲取hostname,自動判斷所在環境,然后執行對應函數。

第三方工具包

上面是根據我們在開發過程中遇到的個性化場景進行來自定義一個裝飾器。

作為一款以工具包著稱的編程語言,Python中也有很多工具包提供了一些實用的裝飾器。

以日志為例,這是每個程序員都無法繞開的。

調試程序對于大多數開發者來說是一項必不可少的工作,當我們想要知道代碼是否按照預期的效果在執行時,我們會想到去輸出一下局部變量與預期的進行比對。目前大多數采用的方法主要有以下幾種:

  • Print函數

  • Log日志

  • IDE調試器

但是這些方法有著無法忽視的弱點:

  • 繁瑣

  • 過度依賴工具

其中有一款不錯的開源工具PySnooper就通過裝飾器把這個問題巧妙的解決了。

PySnooper的調用方式就是通過@pysnooper.snoop的方式進行使用,該裝飾器可以傳入一些參數來實現一些目的,具體如下:

參數描述:

  • None輸出日志到控制臺

  • filePath輸出到日志文件,例如'log/file.log'

  • prefix給調試的行加前綴,便于識別

  • watch查看一些非局部變量表達式的值

  • watch_explode展開值用以查看列表/字典的所有屬性或項

  • depth顯示函數調用的函數的snoop行

舉個例子:

import numpy as np
import pysnooper

@pysnooper.snoop()
def one(number):
    mat = []
    while number:
        mat.append(np.random.normal(0, 1))
        number -= 1
    return mat

one(3)

然后,就會給出如下輸出:

Starting var:.. number = 3
22:17:10.634566 call         6 def one(number):
22:17:10.634566 line         7     mat = []
New var:....... mat = []
22:17:10.634566 line         8     while number:
22:17:10.634566 line         9         mat.append(np.random.normal(0, 1))
Modified var:.. mat = [-0.4142847169210746]
22:17:10.634566 line        10         number -= 1
Modified var:.. number = 2
22:17:10.634566 line         8     while number:
22:17:10.634566 line         9         mat.append(np.random.normal(0, 1))
Modified var:.. mat = [-0.4142847169210746, -0.479901983375219]
22:17:10.634566 line        10         number -= 1
Modified var:.. number = 1
22:17:10.634566 line         8     while number:
22:17:10.634566 line         9         mat.append(np.random.normal(0, 1))
Modified var:.. mat = [-0.4142847169210746, -0.479901983375219, 1.0491540468063252]
22:17:10.634566 line        10         number -= 1
Modified var:.. number = 0
22:17:10.634566 line         8     while number:
22:17:10.634566 line        11     return mat
22:17:10.634566 return      11     return mat
Return value:.. [-0.4142847169210746, -0.479901983375219, 1.0491540468063252]

局部變量值、代碼片段、局部變量所在行號、返回結果等,這些關鍵信息都輸出了,既方便,又清晰。

內置

除了自定義和第三方工具包之外,Python還內置了很多不錯的裝飾器,例如@abc.abstractmethod、@asyncio.coroutine、@classmethod等等。

這里著重提一個非常強大的裝飾器,能夠極大的提升Python的運行速度和效率,通過一個裝飾器能夠將Python代碼的執行速度提升上萬倍,這個裝飾器就是@functools.lru_cache。

以比較知名的斐波那契數列的例子來演示一下。

由于它遞歸計算的過程中,還會用到之前計算的結果,因此會涉及較多的重復計算,下面先看一下正常計算的耗時情況。

import time as tt

def fib(n):
  if n <= 1:
    return n
  return fib(n-1) + fib(n-2)

t1 = tt.time()
fib(30)
print("Time taken: {}".format(tt.time() - t1))
# 0.2073

n等于30時,耗時0.2073。

加上@functools.lru_cache裝飾器再看一下:

import time as tt
import functools

@functools.lru_cache(maxsize=5)
def fib(n):
  if n <= 1:
    return n
  return fib(n-1) + fib(n-2)

t1 = tt.time()
fib(30)
print("Time taken: {}".format(tt.time() - t1))
# 1.811981e-05

耗時為1.811981e-05,足足差了4個量級,快了10000+倍!

關于“Python裝飾器的使用方法有哪些”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“Python裝飾器的使用方法有哪些”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

荔浦县| 富顺县| 岑巩县| 基隆市| 徐水县| 杭州市| 天峨县| 正安县| 收藏| 陇西县| 工布江达县| 绿春县| 拉萨市| 西充县| 泰宁县| 衡水市| 重庆市| 青阳县| 绥德县| 灯塔市| 红原县| 三都| 闵行区| 藁城市| 邵东县| 剑川县| 巴南区| 泾川县| 高陵县| 淳化县| 贡嘎县| 霸州市| 博客| 双柏县| 扶沟县| 鹤壁市| 郎溪县| 房产| 乐安县| 溧水县| 香格里拉县|