器即函數html
裝飾即修飾,意指爲其餘函數添加新功能python
裝飾器定義:本質就是函數,功能是爲其餘函數添加新功能閉包
1.不修改被裝飾函數的源代碼(開放封閉原則)app
2.爲被裝飾函數添加新功能後,不修改被修飾函數的調用方式框架
裝飾器=高階函數+函數嵌套+閉包ide
高階函數定義:
1.函數接收的參數是一個函數名函數
2.函數的返回值是一個函數名spa
3.知足上述條件任意一個,均可稱之爲高階函數3d
def foo(): print('個人函數名做爲參數傳給高階函數') def gao_jie1(func): print('我就是高階函數1,我接收的參數名是%s' %func) func() def gao_jie2(func): print('我就是高階函數2,個人返回值是%s' %func) return func gao_jie1(foo) gao_jie2(foo)
#高階函數應用1:把函數當作參數傳給高階函數 import time def foo(): print('from the foo') def timmer(func): start_time=time.time() func() stop_time=time.time() print('函數%s 運行時間是%s' %(func,stop_time-start_time)) timmer(foo) #總結:咱們確實爲函數foo增長了foo運行時間的功能,可是foo原來的執行方式是foo(),如今咱們須要調用高階函數timmer(foo),改變了函數的調用方式
#高階函數應用2:把函數名當作參數傳給高階函數,高階函數直接返回函數名 import time def foo(): print('from the foo') def timmer(func): start_time=time.time() return func stop_time=time.time() print('函數%s 運行時間是%s' %(func,stop_time-start_time)) foo=timmer(foo) foo() #總結:咱們確實沒有改變foo的調用方式,可是咱們也沒有爲foo增長任何新功能
高階函數總結
1.函數接收的參數是一個函數名
做用:在不修改函數源代碼的前提下,爲函數添加新功能,
不足:會改變函數的調用方式
2.函數的返回值是一個函數名
做用:不修改函數的調用方式
不足:不能添加新功能code
def father(name): print('from father %s' %name) def son(): print('from son') def grandson(): print('from grandson') grandson() son() father('康明')
''' 閉包:在一個做用域裏放入定義變量,至關於打了一個包 ''' def father(name): def son(): # name='alex' print('我爸爸是 [%s]' %name) def grandson(): # name='wupeiqi' print('我爺爺是 [%s]' %name) grandson() son() father('康明')
無參裝飾器=高級函數+函數嵌套
基本框架
#這就是一個實現一個裝飾器最基本的架子 def timer(func): def wrapper(): func() return wrapper
加上參數
def timer(func): def wrapper(*args,**kwargs): func(*args,**kwargs) return wrapper
加上功能
import time def timer(func): def wrapper(*args,**kwargs): start_time=time.time() func(*args,**kwargs) stop_time=time.time() print('函數[%s],運行時間是[%s]' %(func,stop_time-start_time)) return wrapper
加上返回值
import time def timer(func): def wrapper(*args,**kwargs): start_time=time.time() res=func(*args,**kwargs) stop_time=time.time() print('函數[%s],運行時間是[%s]' %(func,stop_time-start_time)) return res return wrapper
使用裝飾器
def cal(array): res=0 for i in array: res+=i return res cal=timer(cal) cal(range(10))
語法糖@
@timer #@timer就等同於cal=timer(cal) def cal(array): res=0 for i in array: res+=i return res cal(range(10))
user_list=[ {'name':'alex','passwd':'123'}, {'name':'linhaifeng','passwd':'123'}, {'name':'wupeiqi','passwd':'123'}, {'name':'yuanhao','passwd':'123'}, ] current_user={'username':None,'login':False} def auth_deco(func): def wrapper(*args,**kwargs): if current_user['username'] and current_user['login']: res=func(*args,**kwargs) return res username=input('用戶名: ').strip() passwd=input('密碼: ').strip() for index,user_dic in enumerate(user_list): if username == user_dic['name'] and passwd == user_dic['passwd']: current_user['username']=username current_user['login']=True res=func(*args,**kwargs) return res break else: print('用戶名或者密碼錯誤,從新登陸') return wrapper @auth_deco def index(): print('歡迎來到主頁面') @auth_deco def home(): print('這裏是你家') def shopping_car(): print('查看購物車啊親') def order(): print('查看訂單啊親') print(user_list) # index() print(user_list) home()
user_list=[ {'name':'alex','passwd':'123'}, {'name':'linhaifeng','passwd':'123'}, {'name':'wupeiqi','passwd':'123'}, {'name':'yuanhao','passwd':'123'}, ] current_user={'username':None,'login':False} def auth(auth_type='file'): def auth_deco(func): def wrapper(*args,**kwargs): if auth_type == 'file': if current_user['username'] and current_user['login']: res=func(*args,**kwargs) return res username=input('用戶名: ').strip() passwd=input('密碼: ').strip() for index,user_dic in enumerate(user_list): if username == user_dic['name'] and passwd == user_dic['passwd']: current_user['username']=username current_user['login']=True res=func(*args,**kwargs) return res break else: print('用戶名或者密碼錯誤,從新登陸') elif auth_type == 'ldap': print('巴拉巴拉小魔仙') res=func(*args,**kwargs) return res return wrapper return auth_deco #auth(auth_type='file')就是在運行一個函數,而後返回auth_deco,因此@auth(auth_type='file') #就至關於@auth_deco,只不過如今,咱們的auth_deco做爲一個閉包的應用,外層的包auth給它留了一個auth_type='file'參數 @auth(auth_type='ldap') def index(): print('歡迎來到主頁面') @auth(auth_type='ldap') def home(): print('這裏是你家') def shopping_car(): print('查看購物車啊親') def order(): print('查看訂單啊親') # print(user_list) index() # print(user_list) home()
import sys,threading,time class KThread(threading.Thread): """A subclass of threading.Thread, with a kill() method. Come from: Kill a thread in Python: http://mail.python.org/pipermail/python-list/2004-May/260937.html """ def __init__(self, *args, **kwargs): threading.Thread.__init__(self, *args, **kwargs) self.killed = False def start(self): """Start the thread.""" self.__run_backup = self.run self.run = self.__run # Force the Thread to install our trace. threading.Thread.start(self) def __run(self): """Hacked run function, which installs the trace.""" sys.settrace(self.globaltrace) self.__run_backup() self.run = self.__run_backup def globaltrace(self, frame, why, arg): if why == 'call': return self.localtrace else: return None def localtrace(self, frame, why, arg): if self.killed: if why == 'line': raise SystemExit() return self.localtrace def kill(self): self.killed = True class Timeout(Exception): """function run timeout""" def timeout(seconds): """超時裝飾器,指定超時時間 若被裝飾的方法在指定的時間內未返回,則拋出Timeout異常""" def timeout_decorator(func): """真正的裝飾器""" def _new_func(oldfunc, result, oldfunc_args, oldfunc_kwargs): result.append(oldfunc(*oldfunc_args, **oldfunc_kwargs)) def _(*args, **kwargs): result = [] new_kwargs = { # create new args for _new_func, because we want to get the func return val to result list 'oldfunc': func, 'result': result, 'oldfunc_args': args, 'oldfunc_kwargs': kwargs } thd = KThread(target=_new_func, args=(), kwargs=new_kwargs) thd.start() thd.join(seconds) alive = thd.isAlive() thd.kill() # kill the child thread if alive: raise Timeout(u'function run too long, timeout %d seconds.' % seconds) else: return result[0] _.__name__ = func.__name__ _.__doc__ = func.__doc__ return _ return timeout_decorator @timeout(5) def method_timeout(seconds, text): print('start', seconds, text) time.sleep(seconds) print('finish', seconds, text) return seconds method_timeout(6,'asdfasdfasdfas')