欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python中裝飾器兼容加括號(hào)和不加括號(hào)的寫(xiě)法詳解

 更新時(shí)間:2017年07月05日 15:20:21   作者:卡瓦邦噶!  
這篇文章主要給大家介紹了關(guān)于Python中裝飾器兼容加括號(hào)和不加括號(hào)寫(xiě)法的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧。

使用Django的時(shí)候,我發(fā)現(xiàn)一個(gè)很神奇的裝飾器: @login_required, 這是控制一個(gè)view的權(quán)限的,比如一個(gè)視圖必須登錄才可以訪問(wèn),可以這樣用:

@login_required
def my_view(request):
 ...
 return render(...)

同時(shí),如果要達(dá)到這樣一種效果:如果用戶(hù)沒(méi)有登錄,那么就把用戶(hù)重定向到登錄界面,可以這樣用:

@login_required(login_url='/accounts/login/')
def my_view(request):
 ...
 return render(...)

所以這個(gè)裝飾器可以帶括號(hào)寫(xiě),又可以不帶括號(hào)寫(xiě)。很神奇有沒(méi)有。正常的接收參數(shù)的裝飾器,就算沒(méi)參數(shù)也應(yīng)該寫(xiě)成@login_required的

好奇去查了一下,在stackoverflow找到一種實(shí)現(xiàn),挺有意思的。先曬出答案:

def doublewrap(f):
 '''
 a decorator decorator, allowing the decorator to be used as:
 @decorator(with, arguments, and=kwargs)
 or
 @decorator
 '''
 @wraps(f)
 def new_dec(*args, **kwargs):
  if len(args) == 1 and len(kwargs) == 0 and callable(args[0]):
   # actual decorated function
   return f(args[0])
  else:
   # decorator arguments
   return lambda realf: f(realf, *args, **kwargs)
 
 return new_dec

使用起來(lái)很簡(jiǎn)單,只要給裝飾器用@doublewrap裝飾一下,這個(gè)裝飾器就支持寫(xiě)括號(hào)和不寫(xiě)括號(hào)兩種寫(xiě)法了。

def test_doublewrap():
 from util import doublewrap
 from functools import wraps 
 
 @doublewrap
 def mult(f, factor=2):
  '''multiply a function's return value'''
  @wraps(f)
  def wrap(*args, **kwargs):
   return factor*f(*args,**kwargs)
  return wrap
 
 # try normal
 @mult
 def f(x, y):
  return x + y
 
 # try args
 @mult(3)
 def f2(x, y):
  return x*y
 
 # try kwargs
 @mult(factor=5)
 def f3(x, y):
  return x - y
 
 assert f(2,3) == 10
 assert f2(2,5) == 30
 assert f3(8,1) == 5*7

原理也不難,只有短短不到10行代碼。

裝飾器我們都知道,是用來(lái)處理一個(gè)函數(shù),返回一個(gè)新的函數(shù)的(如果你不理解裝飾器,可以看一下這個(gè)經(jīng)典的解釋)。

new_func = decorator(func)

我們使用的,就是被裝飾器裝飾的新函數(shù)了。裝飾器只是一個(gè)語(yǔ)法糖,其實(shí)它也是一個(gè)函數(shù),給它傳入一個(gè)函數(shù)作為參數(shù),就返回一個(gè)新的函數(shù)。那么既然裝飾器也是一個(gè)函數(shù),我們就可以用裝飾器裝飾這個(gè)函數(shù)。也就是,“裝飾器的裝飾器”。

裝飾器第一個(gè)參數(shù)肯定是原函數(shù),如果裝飾器可以接收參數(shù)的話,要么第一個(gè)參數(shù)是原函數(shù),后面跟別的參數(shù);要么就只有原函數(shù)一個(gè)參數(shù)。所以,我們這個(gè)“裝飾器的裝飾器”做的事情就是,判斷裝飾器接收的參數(shù),如果只有一個(gè)并且第一個(gè)參數(shù)是可調(diào)用的(callable),那么這就是一個(gè)無(wú)參數(shù)的裝飾器(不需要加括號(hào))。如果還有別的參數(shù),就返回一個(gè)生成裝飾器的函數(shù)(decorator_maker)。

裝飾器是一個(gè)函數(shù)。裝飾器被裝飾過(guò)之后,這個(gè)裝飾器運(yùn)行之前就會(huì)先運(yùn)行裝飾器的裝飾器的代碼,也就是我們的doublewrapp。然后返回值可能是一個(gè)裝飾器,也可能是一個(gè)裝飾器的maker(有參數(shù)的裝飾器),然后裝飾器再執(zhí)行,裝飾原函數(shù)。

這里有點(diǎn)繞,因?yàn)楸緛?lái)裝飾器里面一般就會(huì)有三四層函數(shù)了,(maker, decorator, wrapper, realfunc),再加上一個(gè)裝飾器的裝飾器,會(huì)有點(diǎn)理解困難。如果理解不了,最好不要對(duì)著網(wǎng)上的博文(包括本文)企圖格物致知了,多去看看代碼,多寫(xiě)一寫(xiě)。

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

參考資料

How to create a Python decorator that can be used either with or without parameters?

相關(guān)文章

  • 編寫(xiě)自定義的Django模板加載器的簡(jiǎn)單示例

    編寫(xiě)自定義的Django模板加載器的簡(jiǎn)單示例

    這篇文章主要介紹了編寫(xiě)自定義的Django模板加載器的簡(jiǎn)單示例,Django是各色人氣Python框架中最為著名的一個(gè),需要的朋友可以參考下
    2015-07-07
  • 在python中利用try..except來(lái)代替if..else的用法

    在python中利用try..except來(lái)代替if..else的用法

    今天小編就為大家分享一篇在python中利用try..except來(lái)代替if..else的用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-12-12
  • 什么是Python中的順序表

    什么是Python中的順序表

    在本篇文章里小編給大家整理了一篇關(guān)于Python中順序表詳解的相關(guān)知識(shí)點(diǎn)以及實(shí)例內(nèi)容,需要的朋友們可以參考下。
    2020-06-06
  • python 矢量數(shù)據(jù)轉(zhuǎn)柵格數(shù)據(jù)代碼實(shí)例

    python 矢量數(shù)據(jù)轉(zhuǎn)柵格數(shù)據(jù)代碼實(shí)例

    這篇文章主要介紹了python 矢量數(shù)據(jù)轉(zhuǎn)柵格數(shù)據(jù)代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-09-09
  • Python常用工具類(lèi)之a(chǎn)dbtool示例代碼

    Python常用工具類(lèi)之a(chǎn)dbtool示例代碼

    本文主要介紹了Python中常用工具類(lèi)之a(chǎn)db命令的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • Pandas數(shù)據(jù)分析固定時(shí)間點(diǎn)和時(shí)間差

    Pandas數(shù)據(jù)分析固定時(shí)間點(diǎn)和時(shí)間差

    這篇文章主要介紹了Pandas數(shù)據(jù)分析固定時(shí)間點(diǎn)和時(shí)間差,文章未日澳主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-08-08
  • Python機(jī)器學(xué)習(xí)性能度量利用鳶尾花數(shù)據(jù)繪制P-R曲線

    Python機(jī)器學(xué)習(xí)性能度量利用鳶尾花數(shù)據(jù)繪制P-R曲線

    這篇文章主要為大家介紹了Python機(jī)器學(xué)習(xí)性能度量利用鳶尾花數(shù)據(jù)繪制P-R曲線示例學(xué)習(xí),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • Tkinter組件Checkbutton的具體使用

    Tkinter組件Checkbutton的具體使用

    Checkbutton組件用于實(shí)現(xiàn)確定是否選擇的按鈕,本文主要介紹了Tkinter組件Checkbutton的具體使用,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • python新一代網(wǎng)絡(luò)請(qǐng)求庫(kù)之python-httpx庫(kù)操作指南

    python新一代網(wǎng)絡(luò)請(qǐng)求庫(kù)之python-httpx庫(kù)操作指南

    Python 的 httpx 包是一個(gè)用于 HTTP 交互的一個(gè)優(yōu)秀且靈活的模塊,下面這篇文章主要給大家介紹了關(guān)于python新一代網(wǎng)絡(luò)請(qǐng)求庫(kù)之python-httpx庫(kù)的相關(guān)資料,需要的朋友可以參考下
    2022-09-09
  • Python GUI之tkinter詳解

    Python GUI之tkinter詳解

    今天帶大家學(xué)習(xí)Python GUI之tkinter的相關(guān)知識(shí),文中對(duì)如何使用tkinter作了非常詳細(xì)的介紹及代碼示例,對(duì)正在學(xué)習(xí)python的小伙伴們有很好的幫助,需要的朋友可以參考下
    2021-10-10

最新評(píng)論