python 装饰器有哪些_Python装饰器有哪些常见用途?
RSabet..
123
我使用裝飾器主要用于計(jì)時(shí)目的
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):
...
好例子!不知道它做了什么.解釋你在那里做什么,以及裝飾者如何解決問題將是非常好的. (19認(rèn)同)
在Unix下,`time.clock()`測(cè)量CPU時(shí)間.如果你想測(cè)量掛鐘時(shí)間,你可能想要使用`time.time()`. (11認(rèn)同)
好吧,它衡量`myFunction`運(yùn)行所需的時(shí)間...... (7認(rèn)同)
John Fouhy..
95
我用它們進(jìn)行同步.
import functools
def synchronized(lock):
""" Synchronization decorator """
def wrap(f):
@functools.wraps(f)
def newFunction(*args, **kw):
lock.acquire()
try:
return f(*args, **kw)
finally:
lock.release()
return newFunction
return wrap
正如評(píng)論中指出的那樣,從Python 2.5開始,您可以將with語句與threading.Lock(或multiprocessing.Lock自2.6版本)對(duì)象結(jié)合使用, 以簡(jiǎn)化裝飾器的實(shí)現(xiàn):
import functools
def synchronized(lock):
""" Synchronization decorator """
def wrap(f):
@functools.wraps(f)
def newFunction(*args, **kw):
with lock:
return f(*args, **kw)
return newFunction
return wrap
無論如何,你這樣使用它:
import threading
lock = threading.Lock()
@synchronized(lock)
def do_something():
# etc
@synchronzied(lock)
def do_something_else():
# etc
基本上,它只是把lock.acquire()/ lock.release()在函數(shù)調(diào)用的兩側(cè).
可能是合理的,但裝飾者本質(zhì)上是混亂的,尤其是.來到你身后的第一年的新手,并嘗試修改你的代碼.簡(jiǎn)單地避免這種情況:只需將do_something()將其代碼括在"with lock:"下的塊中,每個(gè)人都可以清楚地看到你的目的.裝飾者被那些想要看起來很聰明的人(實(shí)際上很多人)大量過度使用,但隨后代碼變成了凡人,并且得到了充實(shí). (17認(rèn)同)
@TaylerJones,代碼可讀性是我寫作時(shí)的最高優(yōu)先級(jí).每次修改代碼時(shí),代碼讀取次數(shù)超過7次.難以理解的代碼(對(duì)于新手或在時(shí)間壓力下工作的專家)是每次有人訪問源樹時(shí)必須支付的技術(shù)債務(wù). (17認(rèn)同)
@KevinJ.Rice約束你的代碼,以便'第一年的新手'可以更好地理解它是可怕的做法.Decorator語法更容易閱讀,并且極大地解耦了代碼. (16認(rèn)同)
Simon..
68
我使用裝飾器進(jìn)行類型檢查參數(shù),這些參數(shù)通過一些RMI傳遞給我的Python方法.因此,不是重復(fù)相同的參數(shù)計(jì)數(shù),而是一次又一次地異常提升mumbo-jumbo
def myMethod(ID, name):
if not (myIsType(ID, 'uint') and myIsType(name, 'utf8string')):
raise BlaBlaException() ...
我只是宣布
@accepts(uint, utf8string)
def myMethod(ID, name):
...
和accepts()為我做所有的工作.
對(duì)于任何有興趣的人,在PEP 318中都有`@ accepted`的實(shí)現(xiàn). (15認(rèn)同)
我認(rèn)為有錯(cuò)字..第一種方法應(yīng)該接受..你宣稱兩者都是"myMethod" (2認(rèn)同)
cdleary..
47
裝飾器用于任何您希望透明地"包裝"其他功能的東西.
您可以使用類裝飾器將命名日志添加到類中.
任何足夠通用的功能,你可以"適應(yīng)"現(xiàn)有的類或功能的行為是公平的裝飾游戲.
Torsten Mare..
24
對(duì)于nosetests,您可以編寫一個(gè)裝飾器,它提供具有多組參數(shù)的單元測(cè)試函數(shù)或方法:
@parameters(
(2, 4, 6),
(5, 6, 11),
)
def test_add(a, b, expected):
assert a + b == expected
DNS..
23
Twisted庫使用裝飾器與生成器相結(jié)合,給出異步函數(shù)同步的錯(cuò)覺.例如:
@inlineCallbacks
def asyncf():
doStuff()
yield someAsynchronousCall()
doStuff()
yield someAsynchronousCall()
doStuff()
使用它,本來可以分解成大量小回調(diào)函數(shù)的代碼可以很自然地編寫為單個(gè)塊,使其更容易理解和維護(hù).
MisterMetaph..
12
當(dāng)然,一個(gè)顯而易見的用途是記錄:
import functools
def log(logger, level='info'):
def log_decorator(fn):
@functools.wraps(fn)
def wrapper(*a, **kwa):
getattr(logger, level)(fn.__name__)
return fn(*a, **kwa)
return wrapper
return log_decorator
# later that day ...
@log(logging.getLogger('main'), level='warning')
def potentially_dangerous_function(times):
for _ in xrange(times): rockets.get_rocket(NUCLEAR=True).fire()
DzinX..
8
我主要用它們來調(diào)試(打印一個(gè)打印其參數(shù)和結(jié)果的函數(shù)的包裝)和驗(yàn)證(例如檢查一個(gè)參數(shù)是否是正確的類型,或者在Web應(yīng)用程序的情況下,如果用戶有足夠的權(quán)限調(diào)用一個(gè)特定的方法).
luc..
6
我使用以下裝飾器來創(chuàng)建函數(shù)threadsafe.它使代碼更具可讀性.它幾乎與John Fouhy提出的類似,但不同之處在于,它只能處理單個(gè)函數(shù),并且不需要明確地創(chuàng)建鎖定對(duì)象.
def threadsafe_function(fn):
"""decorator making sure that the decorated function is thread safe"""
lock = threading.Lock()
def new(*args, **kwargs):
lock.acquire()
try:
r = fn(*args, **kwargs)
except Exception as e:
raise e
finally:
lock.release()
return r
return new
class X:
var = 0
@threadsafe_function
def inc_var(self):
X.var += 1
return X.var
那真的很危險(xiǎn).方法inc_var()是"線程安全的",因?yàn)橐淮沃荒苡幸粋€(gè)人調(diào)用它.也就是說,由于該方法對(duì)成員變量"var"進(jìn)行操作,并且可能其他方法也可能對(duì)成員變量"var"進(jìn)行操作,并且這些訪問不是線程安全的,因?yàn)殒i不是共享的.以這種方式做事給X類用戶帶來了錯(cuò)誤的安全感. (5認(rèn)同)
Nikhil Chell..
5
裝飾器既可用于定義函數(shù)的屬性,也可用作修改函數(shù)的樣板; 這是可能的,但反直覺的是他們返回完全不同的功能.看看這里的其他響應(yīng),似乎最常見的用途之一是限制其他一些進(jìn)程的范圍 - 無論是日志記錄,分析,安全檢查等.
CherryPy使用對(duì)象分派來匹配對(duì)象的URL,最終匹配方法.這些方法的裝飾者發(fā)出信號(hào),表明CherryPy是否被允許使用這些方法.例如,改編自教程:
class HelloWorld:
...
def secret(self):
return "You shouldn't be here."
@cherrypy.expose
def index(self):
return "Hello world!"
cherrypy.quickstart(HelloWorld())
aatifh..
5
我最近在使用社交網(wǎng)絡(luò)Web應(yīng)用程序時(shí)使用它們.對(duì)于社區(qū)/團(tuán)體,我應(yīng)該授予成員資格以創(chuàng)建新的討論并回復(fù)您必須成為該特定組成員的消息.所以,我寫了一個(gè)裝飾師@membership_required,把它放在我需要的地方.
總結(jié)
以上是生活随笔為你收集整理的python 装饰器有哪些_Python装饰器有哪些常见用途?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql数据库导入导出_MySQL数据
- 下一篇: python重写和装饰器_python中