麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 編程 > Python > 正文

Python 使用類寫裝飾器的小技巧

2020-02-15 23:05:33
字體:
來源:轉載
供稿:網友

最近學到了一個有趣的裝飾器寫法,就記錄一下。

裝飾器是一個返回函數的函數。寫一個裝飾器,除了最常見的在函數中定義函數以外,Python還允許使用類來定義一個裝飾器。

1、用類寫裝飾器

下面用常見的寫法實現了一個緩存裝飾器。

def cache(func):  data = {}  def wrapper(*args, **kwargs):    key = f'{func.__name__}-{str(args)}-{str(kwargs)})'    if key in data:      result = data.get(key)      print('cached')    else:      result = func(*args, **kwargs)      data[key] = result      print('calculated')    return result  return wrapper

看看緩存的效果。

@cachedef rectangle_area(length, width):  return length * widthrectangle_area(2, 3)# calculated# 6rectangle_area(2, 3)# cached# 6

裝飾器的@cache是一個語法糖,相當于func = cache(func),如果這里的cache不是一個函數,而是一個類又會怎樣呢?定義一個類class Cache, 那么調用func = Cache(func)會得到一個對象,這時返回的func其實是Cache的對象。定義__call__方法可以將類的實例變成可調用對象,可以像調用函數一樣調用對象。然后在__call__方法里調用原本的func函數就能實現裝飾器了。所以Cache類也能當作裝飾器使用,并且能以@Cache的形式使用。

接下來把cache函數改寫為Cache類:

class Cache:  def __init__(self, func):    self.func = func    self.data = {}  def __call__(self, *args, **kwargs):    func = self.func    data = self.data    key = f'{func.__name__}-{str(args)}-{str(kwargs)})'    if key in data:      result = data.get(key)      print('cached')    else:      result = func(*args, **kwargs)      data[key] = result      print('calculated')    return result

再看看緩存結果,效果一樣。

@Cachedef rectangle_area(length, width):  return length * widthrectangle_area(2, 3)# calculated# 6rectangle_area(2, 3)# cached# 6

2、裝飾類的方法

裝飾器不止能裝飾函數,也經常用來裝飾類的方法,但是我發現用類寫的裝飾器不能直接用在裝飾類的方法上。(有點繞…)

先看看函數寫的裝飾器如何裝飾類的方法。

class Rectangle:  def __init__(self, length, width):    self.length = length    self.width = width  @cache  def area(self):    return self.length * self.widthr = Rectangle(2, 3)r.area()# calculated# 6r.area()# cached# 6

但是如果直接換成Cache類會報錯,這個錯誤的原因是area被裝飾后變成了類的一個屬性,而不是方法。

class Rectangle:  def __init__(self, length, width):    self.length = length    self.width = width  @Cache  def area(self):    return self.length * self.widthr = Rectangle(2, 3)r.area()# TypeError: area() missing 1 required positional argument: 'self'Rectangle.area# <__main__.Cache object at 0x0000012D8E7A6D30>r.area# <__main__.Cache object at 0x0000012D8E7A6D30>            
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 嗯~啊~弄嗯~啊h高潮视频 | 国产在线免费 | 日本黄色免费播放 | 欧美1区2区| 毛片在线免费 | 欧美一级电影网站 | 国产日韩免费观看 | 国产精品美女一区二区 | 福利一区二区三区视频在线观看 | 国产精品久久久免费观看 | 91久久国产 | 欧美三级欧美成人高清www | 精品国产一区二区三区四区阿崩 | 国产乱淫av | 韩国一大片a毛片 | 天天天干夜夜夜操 | 久久精品一二三区白丝高潮 | 久久恋 | 1级黄色毛片 | 国产日韩欧美一区 | 青青草最新网址 | 成人免费看片a | 羞羞网站视频 | 国产精品99久久久久久董美香 | 欧美一级做一级爱a做片性 91在线视频观看 | 一区二区三区在线观看国产 | 涩涩操 | 黄色电影免费网址 | 羞羞的网站 | 国产一区二区免费在线观看视频 | 欧美黄在线 | 91九色精品 | 成人在线视频免费 | 国产精品免费久久久久久 | av免费提供 | 国产午夜精品一区二区三区免费 | 国产精品一区99 | 国产乱淫a∨片免费观看 | 看一级大毛片 | xp123精品视频 | 久久久久夜色精品国产老牛91 |