中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python3.5裝飾器原理及應用實例詳解

發布時間:2020-09-08 16:34:03 來源:腳本之家 閱讀:116 作者:loveliuzz 欄目:開發技術

本文實例講述了Python3.5裝飾器原理及應用。分享給大家供大家參考,具體如下:

1、裝飾器:

(1)本質:裝飾器的本質是函數,其基本語法都是用關鍵字def去定義的。

(2)功能:裝飾其他函數,即:為其他函數添加附加功能

(3)原則:不能修改被裝飾的函數的源代碼,不能修改被裝飾的函數的調用方式。即:裝飾器對待被修飾的函數是完全透明的。

(4)簡單應用:統計函數運行時間的裝飾器

import time
#統計函數運行時間的磚裝飾器
def timmer(func):
  def warpper(*args,**kwargs):
    strat_time = time.time()
    func()
    stop_time = time.time()
    print("the func run time is %s" %(stop_time-strat_time))
  return warpper
@timmer
def test1():
  time.sleep(3)
  print("in the test1")
test1()
 

運行結果:

in the test1
the func run time is 3.000171661376953

(5)實現裝飾器知識儲備:

a、函數即“變量”

b、高階函數

c、函數嵌套

d、高階函數+嵌套函數==》裝飾器

2、裝飾器知識儲備——函數即“變量”

定義一個函數,相當于把函數體賦值給這個函數名。

Python解釋器如何回收變量:采用引用計數。當引用有沒有了時(門牌號不存在),變量就被回收了。

函數的定義也有內存回收機制,與變量回收機制一樣。匿名函數沒有函數名,就會被回收。

Python3.5裝飾器原理及應用實例詳解

變量的使用:先定義再調用,只要在調用之前已經存在(定義)即可;函數即“變量”,函數的使用是一樣的。

函數調用順序:其他的高級語言類似,Python 不允許在函數未聲明之前,對其進行引用或者調用

下面的兩段代碼運行效果一樣:

def bar():
  print("in the bar")
def foo():
  print("in the foo")
  bar()
foo()
#python為解釋執行,函數foo在調用前已經聲明了bar和foo,所以bar和foo無順序之分
def foo():
  print("in the foo")
  bar()
def bar():
  print("in the bar")
foo()


運行結果:

in the foo
in the bar
in the foo
in the bar

注意:python為解釋執行,函數foo在調用前已經聲明了bar和foo,所以bar和foo無順序之分

原理圖為:

Python3.5裝飾器原理及應用實例詳解

3、裝飾器知識儲備——高階函數

滿足下列其中一種即可稱之為高階函數:

a、把一個函數名當做實參傳遞給另一個函數(在不修改被裝飾函數的情況下為其添加附加功能)

b、返回值中包含函數名(不修改函數的調用方式)

(1)高階函數示例:

def bar():
  print("in the bar")
def test1(func):
  print(func)  #打印門牌號,即內存地址
  func()
test1(bar)   #門牌號func=bar

運行結果:

<function bar at 0x00BCDFA8>
in the bar

(2)高階函數的妙處——把一個函數名當做實參傳遞給另一個函數(在不修改被裝飾函數的情況下為其添加附加功能)

import time
def bar():
  time.sleep(3)
  print("in the bar")
#test2在不修改被修飾函數bar的代碼時添加了附加的及時功能
def test2(func):
  start_time = time.time()
  func()   #run bar
  stop_time = time.time()
  print("the func run time is %s " %(stop_time-start_time))
#調用方式發生改變,不能像原來的方法去調用被修飾的函數(所以不能實現裝飾器的功能)
test2(bar)
#bar()


運行結果:

in the bar
the func run time is 3.000171661376953

(3)高階函數的妙處——返回值中包含函數名(不修改函數的調用方式)

import time
def bar():
   time.sleep(3)
   print("in the bar")
def test3(func):
  print(func)
  return func
bar = test3(bar)
bar()  #run bar


運行結果:

<function bar at 0x00BADFA8>
in the bar

4、裝飾器知識儲備——嵌套函數

#函數嵌套
def foo():
  print("in the foo")
  def bar():  #bar函數具有局部變量的特性,不能在外部調用,只能在內部調用
    print("in the bar")
  bar()
foo()

運行結果:

in the foo
in the bar

裝飾器應用——模擬網站登錄頁面,訪問需要認證登錄頁面

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author:ZhengzhengLiu
#模擬網站,訪問頁面和部分需要登錄的頁面
import timer
user,passwd = "liu","liu123"
def auth(func):
  def wrapper(*args,**kwargs):
    username = input("Username:").strip()
    password = input("Password:").strip()
    if username == user and password == passwd:
      print("\033[32;1mUser has passed authentication!\033[0m")
      res = func(*args,**kwargs)
      print("-----after authentication---")
      return res
    else:
      exit("\033[31;1mInvalid username or password!\033[0m")
  return wrapper
def index():
  print("welcome to index page!")
@auth
def home():
  print("welcome to index home!")
  return "from home"
@auth
def bbs():
  print("welcome to index bbs!")
#函數調用
index()
print(home())
bbs()
 

運行結果:

welcome to index page!
Username:liu
Password:liu123
User has passed authentication!
welcome to home page!
-----after authentication---
from home
Username:liu
Password:liu123
User has passed authentication!
welcome to bbs page!
-----after authentication---

裝飾器帶參數

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author:ZhengzhengLiu
#模擬網站,訪問頁面和部分需要登錄的頁面,多種認證方式
import timer
user,passwd = "liu","liu123"
def auth(auth_type):
  print("auth func:",auth_type)
  def outer_wrapper(func):
    def wrapper(*args, **kwargs):
      print("wrapper func args:",*args, **kwargs)
      if auth_type == "local":
        username = input("Username:").strip()
        password = input("Password:").strip()
        if username == user and password == passwd:
          print("\033[32;1mUser has passed authentication!\033[0m")
          #被裝飾的函數中有返回值,裝飾器中傳入的參數函數要有返回值
          res = func(*args, **kwargs)  #from home
          print("-----after authentication---")
          return res
        else:
          exit("\033[31;1mInvalid username or password!\033[0m")
      elif auth_type == "ldap":
        print("ldap....")
    return wrapper
  return outer_wrapper
def index():
  print("welcome to index page!")
@auth(auth_type="local")    #利用本地登錄 home = wrapper()
def home():
  print("welcome to home page!")
  return "from home"
@auth(auth_type="ldap")    #利用遠程的ldap登錄
def bbs():
  print("welcome to bbs page!")
#函數調用
index()
print(home())   #wrapper()
bbs()

運行結果:

Python3.5裝飾器原理及應用實例詳解

更多關于Python相關內容可查看本站專題:《Python數據結構與算法教程》、《Python Socket編程技巧總結》、《Python函數使用技巧總結》、《Python字符串操作技巧匯總》及《Python入門與進階經典教程》

希望本文所述對大家Python程序設計有所幫助。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

科技| 西峡县| 长岭县| 冷水江市| 岗巴县| 揭西县| 阜城县| 安仁县| 晋城| 邵阳县| 巴彦淖尔市| 聂拉木县| 阳泉市| 青州市| 浠水县| 扎囊县| 嘉义县| 萨嘎县| 集安市| 西充县| 武定县| 鄂托克旗| 图片| 横山县| 新郑市| 龙井市| 佛坪县| 菏泽市| 辽宁省| 米脂县| 太和县| 青铜峡市| 武隆县| 海淀区| 汕尾市| 东乌珠穆沁旗| 宿州市| 博爱县| 洛南县| 绥化市| 龙南县|