首頁 後端開發 Python教學 python中的裝飾器、生成器與迭代器介紹

python中的裝飾器、生成器與迭代器介紹

Jul 18, 2017 pm 03:25 PM
python

装饰器()

1、装饰器:本质是函数;

装饰器(装饰其他函数),就是为其他函数添加附加功能;

原则:1.不能修改被装饰函数的源代码;

   2.不能修改被装饰的函数的调用方式;

装饰器对被装饰的函数完全透明的,没有修改被装饰函数的代码和调用方式。

实现装饰器知识储备:

1.函数即“变量”;

2.高阶函数;

3.嵌套函数

高阶函数+嵌套函数=》装饰器

匿名函数(lambda表达式)

>>> calc = lambda x:x*3
>>> calc(2)
6

高阶函数:

  a.把一个函数名当做实参传递给另外一个函数;

>>> def bar():  print("in the bar.....")  
>>> def foo(func):
   print(func)>>> foo(bar)
<function bar at 0x7f8b3653cbf8>  
登入後複製


  b.返回值中包含函数名;

>>> import time
>>> def foo():  time.sleep(3)  print("in the foo.....")>>> def main(func):   print(func)   return func>>> t = main(foo)<function foo at 0x7fb7dc9e3378>>>> t()in the foo.....
登入後複製

在不修改源代码的情况下,统计程序运行的时间:

<span style="font-size: 16px">import time</span><br/><br/><span style="font-size: 16px">def timmer(func):</span><br/><span style="font-size: 16px">    def warpper(*args,**kwargs):   #warpper(*args,**kwargs)万能参数,可以指定参数,也可以不指定参数</span><br/><span style="font-size: 16px">        start_time = time.time()     #计算时间</span><br/><span style="font-size: 16px">        func()</span><br/><span style="font-size: 16px">        stop_time = time.time()</span><br/><span style="font-size: 16px">        print("the func run time is %s" %(stop_time-start_time)) #计算函数的运行时间</span><br/><span style="font-size: 16px">    return warpper</span><br/><br/><span style="font-size: 16px">@timmer    #等价于test1 = timmer(test1),因此函数的执行调用是在装饰器里面执行调用的</span><br/><span style="font-size: 16px">def test1():</span><br/><span style="font-size: 16px">    time.sleep(3)</span><br/><span style="font-size: 16px">    print("in the test1")</span><br/><br/><span style="font-size: 16px">test1()<br/>运行结果如下:<br/></span>
登入後複製

in the test1
the func run time is 3.001983404159546

装饰器带参数的情况:

<span style="font-size: 16px; font-family: 宋体">import time</span><br/><br/><span style="font-size: 16px; font-family: 宋体">def timmer(func):</span><br/><span style="font-size: 16px; font-family: 宋体">    def warpper(*args,**kwargs):</span><br/><span style="font-size: 16px; font-family: 宋体">        start_time = time.time()     #计算时间</span><br/><span style="font-size: 16px; font-family: 宋体">        func(*args,**kwargs)  #执行函数,装饰器参数情况</span><br/><span style="font-size: 16px; font-family: 宋体">        stop_time = time.time()</span><br/><span style="font-size: 16px; font-family: 宋体">        print("the func run time is %s" %(stop_time-start_time)) #计算函数的运行时间</span><br/><span style="font-size: 16px; font-family: 宋体">    return warpper    #返回内层函数名</span><br/><br/><span style="font-size: 16px; font-family: 宋体">@timmer</span><br/><span style="font-size: 16px; font-family: 宋体">def test1():</span><br/><span style="font-size: 16px; font-family: 宋体">    time.sleep(3)</span><br/><span style="font-size: 16px; font-family: 宋体">    print("in the test1")</span><br/><br/><span style="font-size: 16px; font-family: 宋体">@timmer    #test2 = timmer(test2)</span><br/><span style="font-size: 16px; font-family: 宋体">def test2(name):</span><br/><span style="font-size: 16px; font-family: 宋体">    print("in the test2 %s" %name)</span><br/><br/><span style="font-size: 16px; font-family: 宋体">test1()</span><br/><span style="font-size: 16px; font-family: 宋体">test2("alex")<br/>运行结果如下:<br/></span>
登入後複製

in the test1
the func run time is 3.0032410621643066
in the test2 alex
the func run time is 2.3603439331054688e-05

装饰器返回值情况:

import time
user,passwd = "alex","abc123"def auth(func):
    def wrapper(*args,**kwargs):
        username = input("Username:").strip()
        password = input("Password:").strip()if user == username and passwd == password:
            print("\033[32;1mUser has passed authentication.\033[0m")return func(*args,**kwargs)   #实际上执行调用的函数   
            # res = func(*args,**kwargs)
            # 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 home page...")return "form home..."@auth
def bbs():
    print("welcome to bbs page")

index()
print(home())
bbs()
登入後複製

装饰器带参数的情况:

实现:1、本地验证;2、远程验证

import time
user,passwd = "alex","abc123"def auth(auth_type):&#39;&#39;&#39;函数的多层嵌套,先执行外层函数&#39;&#39;&#39;print("auth_type",auth_type)
    def out_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 user == username and passwd == password:
                    print("\033[32;1mUser has passed authentication.\033[0m")
                    func(*args,**kwargs)   #实际上执行调用的函数
                    # res = func(*args,**kwargs)
                    # return res   #函数返回值的情况,因为装饰器调用的时候是在装饰器调用的函数,因此返回值也在这个函数中else:
                    exit("\033[31;1mInvalid username or password.\033[0m")
            elif auth_type == "ldap":
                print("搞毛线lbap,傻逼....")return wrapperreturn out_wrapper


def index():
    print("welcome to index page...")

@auth(auth_type="local")
def home():
    #用户自己页面
    print("welcome to home page...")return "form home..."@auth(auth_type="ldap")
def bbs():
    print("welcome to bbs page")

index()
home()
bbs()   #函数没有,因为没有调用函数,函数的调用在装饰器里面,是装饰器调用了函数
登入後複製

  迭代器和生成器

  生成器

  通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。

  所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。

  >>> l1 = (i for i in range(10))
  >>> l1
   at 0x7f6a9fbcaeb8>
  >>> l1.__next__()
  0
  >>> l1.__next__()
  1
  生成器:只有在调用时才会生成相应的数据;

  只有通过__next__()方法进行执行,这种能够记录程序运行的状态,yield用来生成迭代器函数。(只能往后调用,不能向前或者往后推移,只记住当前状态,因此银行的系统用来记录的时候可以使用yield函数)。

 %=  %= consumer(= consumer( i  range(,)

运行如下:
A准备吃包子了......
B准备吃包子了......
包子1被A吃了......
包子1被B吃了......
包子2被A吃了......
包子2被B吃了......
包子3被A吃了......
包子3被B吃了......
包子4被A吃了......
包子4被B吃了......
包子5被A吃了......
包子5被B吃了......
包子6被A吃了......
包子6被B吃了......
包子7被A吃了......
包子7被B吃了......
包子8被A吃了......
包子8被B吃了......
包子9被A吃了......
包子9被B吃了.....
登入後複製

  迭代器

  我们已经知道,可以直接作用于for循环的数据类型有以下几种:

  一类是集合数据类型,如listtupledictsetstr等;

  一类是generator,包括生成器和带yield的generator function。

  这些可以直接作用于for循环的对象统称为可迭代对象:Iterable

  可以使用isinstance()判断一个对象是否是Iterable对象

>>> from collections import Iterable
>>> isinstance([], Iterable)
True
>>> isinstance({}, Iterable)
True
>>> isinstance(&#39;abc&#39;, Iterable)
True
>>> isinstance((x for x in range(10)), Iterable)
True
>>> isinstance(100, Iterable)
False
登入後複製

以上是python中的裝飾器、生成器與迭代器介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1668
14
CakePHP 教程
1428
52
Laravel 教程
1329
25
PHP教程
1273
29
C# 教程
1256
24
PHP和Python:解釋了不同的範例 PHP和Python:解釋了不同的範例 Apr 18, 2025 am 12:26 AM

PHP主要是過程式編程,但也支持面向對象編程(OOP);Python支持多種範式,包括OOP、函數式和過程式編程。 PHP適合web開發,Python適用於多種應用,如數據分析和機器學習。

在PHP和Python之間進行選擇:指南 在PHP和Python之間進行選擇:指南 Apr 18, 2025 am 12:24 AM

PHP適合網頁開發和快速原型開發,Python適用於數據科學和機器學習。 1.PHP用於動態網頁開發,語法簡單,適合快速開發。 2.Python語法簡潔,適用於多領域,庫生態系統強大。

sublime怎麼運行代碼python sublime怎麼運行代碼python Apr 16, 2025 am 08:48 AM

在 Sublime Text 中運行 Python 代碼,需先安裝 Python 插件,再創建 .py 文件並編寫代碼,最後按 Ctrl B 運行代碼,輸出會在控制台中顯示。

PHP和Python:深入了解他們的歷史 PHP和Python:深入了解他們的歷史 Apr 18, 2025 am 12:25 AM

PHP起源於1994年,由RasmusLerdorf開發,最初用於跟踪網站訪問者,逐漸演變為服務器端腳本語言,廣泛應用於網頁開發。 Python由GuidovanRossum於1980年代末開發,1991年首次發布,強調代碼可讀性和簡潔性,適用於科學計算、數據分析等領域。

Python vs. JavaScript:學習曲線和易用性 Python vs. JavaScript:學習曲線和易用性 Apr 16, 2025 am 12:12 AM

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

Golang vs. Python:性能和可伸縮性 Golang vs. Python:性能和可伸縮性 Apr 19, 2025 am 12:18 AM

Golang在性能和可擴展性方面優於Python。 1)Golang的編譯型特性和高效並發模型使其在高並發場景下表現出色。 2)Python作為解釋型語言,執行速度較慢,但通過工具如Cython可優化性能。

vscode在哪寫代碼 vscode在哪寫代碼 Apr 15, 2025 pm 09:54 PM

在 Visual Studio Code(VSCode)中編寫代碼簡單易行,只需安裝 VSCode、創建項目、選擇語言、創建文件、編寫代碼、保存並運行即可。 VSCode 的優點包括跨平台、免費開源、強大功能、擴展豐富,以及輕量快速。

notepad 怎麼運行python notepad 怎麼運行python Apr 16, 2025 pm 07:33 PM

在 Notepad 中運行 Python 代碼需要安裝 Python 可執行文件和 NppExec 插件。安裝 Python 並為其添加 PATH 後,在 NppExec 插件中配置命令為“python”、參數為“{CURRENT_DIRECTORY}{FILE_NAME}”,即可在 Notepad 中通過快捷鍵“F6”運行 Python 代碼。

See all articles