日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > python >内容正文

python

python基础教程:装饰器的高级应用

發(fā)布時(shí)間:2025/3/20 python 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python基础教程:装饰器的高级应用 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

裝飾器和裝飾器模式

裝飾器模式是面向?qū)ο蟮囊环N設(shè)計(jì)模式,支持將行為動(dòng)態(tài)增加到已經(jīng)存在的對(duì)象上。當(dāng)裝飾一個(gè)對(duì)象的時(shí)候,就表示獨(dú)立與其他類實(shí)例對(duì)象,為該對(duì)象擴(kuò)展了新的功能。

python的裝飾器不是裝飾器模式的一種實(shí)現(xiàn)。python裝飾器是在定義的時(shí)候?qū)瘮?shù)或方法增加功能,而不是在運(yùn)行的時(shí)候增加。
裝飾器模式可以在python中實(shí)現(xiàn),但是這樣做意義不大。因?yàn)閜ython是鴨子類型風(fēng)格的編程語(yǔ)言。鴨子類型(英語(yǔ):duck typing)是動(dòng)態(tài)類型的一種風(fēng)格。

一個(gè)基礎(chǔ)的裝飾器

import time import datetimedef time_this(original_func):def new_func(*args, **kwargs):start_a = datetime.datetime.now()x = original_func(*args, **kwargs)end_a = datetime.datetime.now()print("Elapsed Time = {0}".format(start_a - end_a))return xreturn new_func@time_this def func_a(stuff):print("i need a sleep.")time.sleep(3)func_a(1)

運(yùn)行結(jié)果:

i need a sleep. Elapsed Time = -1 day, 23:59:56.999700

帶有參數(shù)的裝飾器

有時(shí)候,除了完成其裝飾的函數(shù)外,還可以帶上參數(shù)。這種技術(shù)常用于注冊(cè)類似功能。比如:

@view_config(route_name='home',renderer='templates/mytemplate.pt') def my_view(request):return {'project':'hello decorators'}

假設(shè)有個(gè)應(yīng)用,用戶可以通過(guò)gui登錄。用戶和gui觸發(fā)時(shí)間交互調(diào)用python函數(shù)。不同的用戶有不同的權(quán)限。執(zhí)行不同的函數(shù)需要不同了類型的權(quán)限。比如:

#assume these functions exist def current_user_id():"""this function returns the current logged in user id, if the user is not authenticated then return None"""def get_permissions(iUserId):"""returns a list of permission strings for the given user. For example ['logged_in','administrator','premium_member']"""#we need to implment permission checking on these functionsdef delete_user(iUserId):"""delete the user with the given Id. This function is only accessable to users with administrator permissions"""def new_game():"""any logged in user can start a new game"""def premium_checkpoint():"""save the game progress, only accessable to premium members"""

實(shí)現(xiàn)的方法之一是使用多個(gè)裝飾器:

''' 遇到問(wèn)題沒(méi)人解答?小編創(chuàng)建了一個(gè)Python學(xué)習(xí)交流QQ群:531509025 尋找有志同道合的小伙伴,互幫互助,群里還有不錯(cuò)的視頻學(xué)習(xí)教程和PDF電子書! ''' def requires_admin(func):def ret_func(*args,**kwargs):permissions = get_permissions(current_user_id())if 'administrator' in permissions:return func(*args,**kwargs)else:raise Exception("Not allowed")return ret_funcdef requires_logged_in(func):def ret_func(*args,**kwargs):permissions = get_permissions(current_user_id())if 'logged_in' in permissions:return func(*args,**kwargs)else:raise Exception("Not allowed")return ret_funcdef requires_premium_member(func):def ret_func(*args,**kwargs):permissions = get_permissions(current_user_id())if 'premium_member' in permissions:return func(*args,**kwargs)else:raise Exception("Not allowed")return ret_func@requires_admin def delete_user(iUserId):"""delete the user with the given Id. This function is only accessable to users with administrator permissions"""@requires_logged_in def new_game():"""any logged in user can start a new game"""@requires_premium_member def premium_checkpoint():"""save the game progress, only accessable to premium members"""

但是這樣的話,需要多個(gè)裝飾器。如果有權(quán)限檢查模塊程序發(fā)生變動(dòng),就需要逐一修改裝飾器。難道不可以通過(guò)一個(gè)裝飾器來(lái)實(shí)現(xiàn)么?

答案是:有。我們需要一個(gè)返回結(jié)果是裝飾器的函數(shù)。

def requires_permission(sPermission): def decorator(func): def decorated(*args,**kwargs): permissions = get_permissions(current_user_id()) if sPermission in permissions: return func(*args,**kwargs) raise Exception("permission denied") return decorated return decorator def get_permissions(iUserId): #this is here so that the decorator doesn't throw NameErrorsreturn ['logged_in',]def current_user_id(): #ditto on the NameErrorsreturn 1#and now we can decorate stuff... @requires_permission('administrator') def delete_user(iUserId):"""delete the user with the given Id. This function is only accessible to users with administrator permissions"""@requires_permission('logged_in') def new_game():"""any logged in user can start a new game"""@requires_permission('premium_member') def premium_checkpoint():"""save the game progress, only accessable to premium members"""

通用的裝飾器代碼示例:

def outer_decorator(*outer_args,**outer_kwargs): def decorator(func): def decorated(*args,**kwargs): do_something(*outer_args,**outer_kwargs) return func(*args,**kwargs) return decorated return decorator @outer_decorator(1,2,3) def foo(a,b,c):print aprint bprint c foo()

等價(jià)于:

''' 遇到問(wèn)題沒(méi)人解答?小編創(chuàng)建了一個(gè)Python學(xué)習(xí)交流QQ群:531509025 尋找有志同道合的小伙伴,互幫互助,群里還有不錯(cuò)的視頻學(xué)習(xí)教程和PDF電子書! ''' def decorator(func): def decorated(*args,**kwargs): do_something(1,2,3) return func(*args,**kwargs) return decorated return decorator @decorator def foo(a,b,c):print aprint bprint cfoo()

裝飾類

裝飾器并不僅僅限于裝飾函數(shù),也可以裝飾類。

假如我們有個(gè)類,需要完成很多重要工作,我們想計(jì)時(shí)這個(gè)類完成每項(xiàng)工作需要的時(shí)間。我們可以使用上面定義好的time_this:

class ImportantStuff(object):@time_thisdef do_stuff_1(self):...@time_thisdef do_stuff_2(self):...@time_thisdef do_stuff_3(self):...

上面這樣做是可以實(shí)現(xiàn),但是要添加很多額外的代碼行在類定義中。

如果我們寫了很多類的方法,忘記了其中對(duì)其中個(gè)別函數(shù)進(jìn)行裝飾怎么辦?或者如果我們不再需要計(jì)時(shí)功能呢。

可使用以下的方式進(jìn)行優(yōu)化:

@time_all_class_methods class ImportantStuff:def do_stuff_1(self):...def do_stuff_2(self):...def do_stuff_3(self):...

上面的代碼等價(jià)于:

class ImportantStuff:def do_stuff_1(self):...def do_stuff_2(self):...def do_stuff_3(self):...ImportantStuff = time_all_class_methods(ImportantStuff)

那么time_all_class_methods是如何工作的呢?

首先、它需要一個(gè)類作為參數(shù),并返回一個(gè)類。返回的類的功能看起來(lái)應(yīng)該和原先的importstuff類類似。這里我們可以這么做:

import datetime import timedef time_this(original_func): print ("decorating") def new_func(*args,**kwargs):print("starting timer") start = datetime.datetime.now() x = original_func(*args,**kwargs) end = datetime.datetime.now() print "Elapsed Time = {0}".format(end-start) return x return new_funcdef time_all_class_methods(Cls):class NewCls(object):def __init__(self,*args,**kwargs):self.oInstance = Cls(*args,**kwargs)def __getattribute__(self,s):"""this is called whenever any attribute of a NewCls object is accessed. This function first tries toget the attribute off NewCls. If it fails then it tries to fetch the attribute from self.oInstance (aninstance of the decorated class). If it manages to fetch the attribute from self.oInstance, andthe attribute is an instance method then `time_this` is applied."""try: x = super(NewCls,self).__getattribute__(s)except AttributeError: passelse:return xx = self.oInstance.__getattribute__(s)if type(x) == type(self.__init__): # it is an instance methodreturn time_this(x) # this is equivalent of just decorating the method with time_thiselse:return xreturn NewCls#now lets make a dummy class to test it out on:@time_all_class_methods class Foo(object):def a(self):print "entering a"import timetime.sleep(3)print "exiting a"oF = Foo() oF.a()

總結(jié)

以上是生活随笔為你收集整理的python基础教程:装饰器的高级应用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。