1. 程式人生 > >python-day11~12_裝飾器

python-day11~12_裝飾器

# 三元運算子
# 接收結果的變數 = 條件為真的結果 if 條件 else 條件為假的結果

a if a > b else b

 

1,裝飾器

import time
def func():
    time.sleep(0.01)
    print('大家好!')

def timmer(f):  #裝飾器函式
    def inner():
        start = time.time()
        f()       #被裝飾的函式
        end = time.time()
        print(end - start)
    
return inner func = timmer(func) func()

# 裝飾器的作用 —— 不想修改函式的呼叫方式 但是還想在原來的函式前後新增功能
# timmer就是一個裝飾器函式,只是對一個函式 有一些裝飾作用

# 原則: 開放封閉原則
# 開放 : 對擴充套件是開放的
# 封閉 : 對修改是封閉的。原函式內部不能改

其設計核心就是整個軟體框架,對擴充套件是開放的,對修改是封閉的。也就是說,當軟體有新的需求變化的時候,只需要通過對軟體框架進行擴充套件來適應新的需求,而不是對框架內部的程式碼進行修改。

 

2,語法糖

import time

def timmer(f):  #裝飾器函式
    def inner(): start = time.time() f() #被裝飾的函式 end = time.time() print(end - start) return inner

@timmer @語法糖,功能與func = timmer(func)一樣。要緊貼被裝飾的函式
def func(): time.sleep(0.01) print('大家好!') #func = timmer(func) func()

 

3,裝飾器的固定模板

from functools import wraps  #以將原函式物件的指定屬性複製給包裝函式物件

def wrapper(func):  #qqxing

       @wraps(func)   #呼叫functool import
  def inner(*args,**kwargs):
    ret = func(*args,**kwargs)  #被裝飾的函式
    return ret
  return inner

@wrapper  #qqxing = wrapper(qqxing)
def qqxing():
  print(123)

 

# print(wahaha.__name__) #檢視字串格式的函式名,依靠founctool import
# print(wahaha.__doc__) #document

 

4,

裝飾器函式最多三層巢狀

#帶引數的裝飾器
#500個函式
# import time
# FLAGE = False   #用FLAG來控制裝飾器是否生效
# def timmer_out(flag):
  # def timmer(func):
    # def inner(*args,**kwargs):
      # if flag:
        # start = time.time()
        # ret = func(*args,**kwargs)
        # end = time.time()
        # print(end-start)
        # return ret
      # else:
        # ret = func(*args, **kwargs)
        # return ret
    # return inner
  # return timmer
# # timmer = timmer_out(FLAGE)
# @timmer_out(FLAGE)   #wahaha = timmer(wahaha)
# def wahaha():
  # time.sleep(0.1)
  # print('wahahahahahaha')
#
# @timmer_out(FLAGE)
# def erguotou():
  # time.sleep(0.1)
  # print('erguotoutoutou')

# wahaha()
# erguotou()

<python核心程式設計-第二版>

 

5,

#多個裝飾器裝飾一個函式
def wrapper1(func):
  def inner1():
    print('wrapper1 ,before func')
    ret = func()
    print('wrapper1 ,after func')
    return ret
  return inner1

def wrapper2(func):
  def inner2():
    print('wrapper2 ,before func')
    ret = func()
    print('wrapper2 ,after func')
    return ret
  return inner2

def wrapper3(func):
  def inner3():
    print('wrapper3 ,before func')
    ret = func()
    print('wrapper3 ,after func')
    return ret
  return inner3

@wrapper3
@wrapper2  #第二步,wrapper1 = wrapper2(wrapper1)  = wrapper2(inner1) = inner2
@wrapper1  #第一步,f = wrapper1(f) = inner1
def f():
  print('in f')
  return '哈哈哈'

print(f())

 

作業:

 

'''
# 1.默寫:帶引數的裝飾器。需要標註程式碼的執行步驟。
# 2.整理作業:函式的知識點以及裝飾器相關作業。裝飾器作業需要自己寫一遍,並給作業加註釋。
#1
# def wrapper(fu):
# def inner(*args,**kwargs):
# ret = fu(*args,**kwargs)
# return ret
# return inner
#
# @wrapper #func = wrapper(func)
# def func(*args,**kwargs):
# pass

#分析使用者輸入的命令,按空格進行分割
#1) select查詢功能
#2)定義輸出的內容和格式順序
#3)where操作部分,找出對應的列
#4)按照本處關鍵字定位列
#5)判斷部分,判斷為真就輸出
#6)判斷,或要查詢的引數

#1,輸入的命令按空格分開
#2,如命令第1個字串是select,呼叫select_func函式
#2.1 檢查長度,如等4,呼叫judge函式
#2.1.1,judge(),檢查字串中的> < =,執行檔案行中的判斷查詢,並呼叫show_data函式輸出
#2.2,如長度大於4 ,第5個字元是'like',呼叫search函式
#2.2.1,search(),檢查對應列中的引數是否存在,並呼叫show_data函式輸出
#2.3,show_data(),按逗號分割引數,把檔案中對應引數的部分列印輸出;如是*星號,列印本行即可

#3,命令如是quit就退出
'''



def select_func(*args):
#分析指令和引數
#查詢檔案內容並輸出
'''
用途:select函式
變數列表:
com_item為要判斷的列
com_value為要判斷的值
com_print_index為要列印輸出列的索引值
命令列命名com_list:select com_print_index where com_item>com_value
com = 'select * where age>22'
:param args:
:return:
'''

def get_index(i):
# if count == 0: # 確認是第一行,即格式行,任務:1查詢輸出項索引值;2找到判斷項索引值
context_head_list = i.split(',')
context_head_length = len(context_head_list)
count1 = 0
flage = False
com_item_index = 0
while flage == False and len(context_head_list) > count1: # 找到要判斷列的索引值
if com_item in context_head_list[count1]:
com_item_index = count1 # 拿到判斷項的索引值
flage = True
count1 += 1
if count1 == context_head_length:
print('你要找的項中,有的不存在')
# 找到輸出項列的索引值
com_list_item = com_list[1].split(',')
if com_list[1] == '*':
for ii in range(0, len(context_head_list)):
com_print_index.append(ii)
else:
for ii in com_list_item: # 對命令列輸出項格式進行迴圈
count2 = 0
flag = False
while flag == False and context_head_length > count2: # 找要查詢的列的索引值
if ii == context_head_list[count2]:
com_print_index.append(count2) # 拿到要輸出項列的索引值
flag = True
count2 += 1
if count2 == context_head_length:
print('你要找的項中,有的不存在')
return com_print_index, com_item_index

def show_data(com_fomat, line):
# print(com_fomat,line)
line_print2 = []
if com_fomat == '*':
print(line.replace('\n', ''))
else:
line_print1 = line.replace('\n', '').split(',')
for i in list(com_fomat):
line_print2.append(line_print1[i])
print(' '.join(line_print2))

com_list = list(args)
# print(com_list)
with open('員工資訊表.txt', mode='r', encoding='utf-8') as f:
count = 0
com_print_index = []
com_item_index = 0
context_head_list = []
if len(com_list) == 4: # 說明是<>=的判斷操作
if '>'in com_list[3]: #說明是>查詢
com_item,com_value = com_list[3].split('>')
for i in f:
# print('這是i', i,'還沒有判斷')
if count == 0: # 確認是第一行,即格式行,任務:1查詢輸出項索引值;2找到判斷項索引值
com_print_index, com_item_index = get_index(i)
else: # 正式資料,非格式行,進行內容判斷查詢並列印
# print(count,context_head_list)
# 滿足select中的查詢條件時列印
context_list = i.replace('\n', '').split(',')
if int(context_list[com_item_index]) > int(com_value): # <>=運算,轉成整型後運算
show_data(com_print_index, i)
count += 1
elif '<'in com_list[3]:
# print('處理<=部分')
com_item, com_value = com_list[3].split('<')
for i in f:
# print('這是i', i,'還沒有判斷')
if count == 0: # 確認是第一行,即格式行,任務:1查詢輸出項索引值;2找到判斷項索引值
com_print_index, com_item_index = get_index(i)
else: # 正式資料,非格式行,進行內容判斷查詢並列印
# print(count,context_head_list)
# 滿足select中的查詢條件時列印
context_list = i.replace('\n', '').split(',')
if int(context_list[com_item_index]) < int(com_value): # <>=運算,轉成整型後運算
show_data(com_print_index, i)
count += 1
else:
# print('處理剩下的=部分,不用再if語句判斷了')
com_item, com_value = com_list[3].split('=')
for i in f:
# print('這是i', i,'還沒有判斷')
if count == 0: # 確認是第一行,即格式行,任務:1查詢輸出項索引值;2找到判斷項索引值
com_print_index, com_item_index = get_index(i)
else: # 正式資料,非格式行,進行內容判斷查詢並列印
# print(count,context_head_list)
# 滿足select中的查詢條件時列印
context_list = i.replace('\n', '').split(',')
if context_list[com_item_index] == com_value: # =運算,可能是str或int
show_data(com_print_index, i)
count += 1
elif len(com_list) == 6 and 'like' in com_list: # 說明是like的判斷操作
com_item, com_value = com_list[3], com_list[5]
for i in f:
# print('這是like', com_item, com_value)
if count == 0: # 確認是第一行,即格式行,任務:1查詢輸出項索引值;2找到判斷項索引值
com_print_index, com_item_index = get_index(i)
else: # 正式資料,非格式行,進行內容判斷查詢並列印
# print(count,context_head_list)
# 滿足select中的查詢條件時列印
context_list = i.replace('\n', '').split(',')
if com_value in context_list[com_item_index]: # <>=運算,轉成整型後運算
show_data(com_print_index, i)
count += 1


us_command = input('**員工資訊表程式**\n>>>').strip()
us_command = us_command.split()
# print(us_command,len(us_command))
if us_command[0].lower() == 'select':
select_func(*us_command)
else:
print('對不起,命令無法識別!')