python 之 函數 裝飾器

5.8 裝飾器

1 開放封閉原則 軟件一旦上線後,就應該遵循開放封閉原則,即對修改源代碼是封閉的,對功能的擴展是開放的 也就是說咱們必須找到一種解決方案: 可以在不修改一個功能源代碼以及調用方式的前提下,爲其加上新功能 原則以下: 一、不修改源代碼 二、不修改調用方式 目的: 在遵循1和2原則的基礎上擴展新功能mysql

裝飾器: 裝飾器即在不修改被裝飾對象源代碼與調用方式的前提下,爲被裝飾器對象添加新功能,裝飾器與被裝飾的對象都可以是任意可調用的對象sql

裝飾器 ===》函數 被裝飾的對象 ===》函數app

5.81 無參裝飾器舉例

import time
def index():
   time.sleep(3)
   print('welcome to index page')
def outter(func): #func=最原始的index
   def wrapper():
       start_time=time.time()
       func()
       stop_time=time.time()
       print(stop_time-start_time)
   return wrapper

index=outter(index) # 新的index=wrapper
index()   #wrapper()
welcome to index page
3.0000429153442383

5.82 無參裝飾器升級

import time
def index():
   time.sleep(1)
   print('welcome to index page')
   return 122
def home(name):
   time.sleep(2)
   print('welcome %s to home page' %name)
#==============裝飾器
def timmer(func): #func=最原始的index
   def wrapper(*args,**kwargs):
       start_time=time.time()
       res=func(*args,**kwargs) #調用最原始的index
       stop_time=time.time()
       print(stop_time-start_time)
       return res
   return wrapper

index=timmer(index) # 新的index=wrapper
home=timmer(home) #新的home=wrapper
# ==========================================

res=index() #res=wrapper()
print(res)
res=home(name='egon') #res=wrapper(name='egon')
print(res)

5.83 無參裝飾器模板:

def index():
   pass
#==============裝飾器
def outer(func):
   def inner(*args,**kwargs):
       res=func(*args,**kwargs)
       return res
   return inner

index=outer(index)
# ==========================================
res=index()
print(res)

使用:在被裝飾對象正上方單獨一行,@無參裝飾器名函數

@無參裝飾器名
def foo():
   pass

5.84 裝飾器語法糖

import time
def timmer(func):
   def wrapper(*args,**kwargs):
       start_time=time.time()
       res=func(*args,**kwargs)
       stop_time=time.time()
       print(stop_time-start_time)
       return res
   return wrapper

@timmer #index=timmer(index)
def index():
   time.sleep(1)
   print('welcome to index page')
   return 122

@timmer # home=timmer(home)
def home(name):
   time.sleep(2)
   print('welcome %s to home page' %name)

index()
home('egon')

5.85 疊加裝飾器

import time
current_user={
   'username':None,
}

def auth(func): # func=index
   def wrapper(*args,**kwargs):
       if current_user['username']:
           print('已經登錄過了')
           res=func(*args,**kwargs)
           return res
       uname=input('用戶名>>: ').strip()
       pwd=input('密碼>>: ').strip()
       if uname == 'egon' and pwd == '123':
           print('登錄成功')
           current_user['username']=uname
           res=func(*args,**kwargs)
           return res
       else:
           print('用戶名或密碼錯誤')
   return wrapper

def timmer(func):
   def wrapper(*args,**kwargs):
       start_time=time.time()
       res=func(*args,**kwargs)
       stop_time=time.time()
       print(stop_time-start_time)
       return res
   return wrapper

@timmer # timmer 統計的是auth+index的執行時間
@auth
def index():
   time.sleep(1)
   print('welcome to index page')
   return 122

index()

5.86 有參裝飾器

import time
current_user={
   'username':None
}
def auth(engine): # engine='file' #添加一層函數傳engine值
   def auth2(func): # func=index
       def wrapper(*args,**kwargs):
           if engine == 'file':
               if current_user['username']:
                   print('已經登錄過了')
                   res=func(*args,**kwargs)
                   return res
               uname=input('用戶名>>: ').strip()
               pwd=input('密碼>>: ').strip()
               if uname == 'egon' and pwd == '123':
                   print('登錄成功')
                   current_user['username']=uname
                   res=func(*args,**kwargs)
                   return res
               else:
                   print('用戶名或密碼錯誤')
           elif engine == 'mysql':
               print('基於MyQL的認證')
           elif engine == 'ldap':
               print('基於LDAP的認證')
       return wrapper
   return auth2
#auth_src=auth('ldap')
#@auth_src

@auth('ldap') # @auth2 #index=auth2(index) #index=wrapper
def index():
   time.sleep(1)
   print('welcome to index page')
   return 122

index() # wrapper()

5.87 有參裝飾器模板

def outter2(x,y,z):
   def outter(func):
       def wrapper(*args,**kwargs):
           res=func(*args,**kwargs)
           return res
       return wrapper
   return outter
@outer2(1,2,3)
# ==========================================
def index():
   pass
res=index()
print(res)

使用:在被裝飾對象正上方單獨一行,@有參裝飾器名(1,2,3)ui

@有參裝飾器名(1,2,3)
def foo():
   pass
相關文章
相關標籤/搜索