亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

詳解Python中的三器一閉

 更新時(shí)間:2023年05月04日 11:09:53   作者:以山河作禮。  
這篇文章主要介紹了詳解Python中的三器一閉,Python中的三器一閉是指迭代器、裝飾器、生成器和閉包,需要的朋友可以參考下

迭代器

什么是迭代

迭代是重復(fù)反饋過(guò)程的活動(dòng),其目的通常是為了逼近所需目標(biāo)或結(jié)果。每一次對(duì)過(guò)程的重復(fù)稱為一次“迭代”,而每一次迭代得到的結(jié)果會(huì)作為下一次迭代的初始值。

在python中,迭代是訪問(wèn)集合元素的一種方式。對(duì)list、tuple、str等類型的數(shù)據(jù)使用for…in…的循環(huán)語(yǔ)法從其中依次拿到數(shù)據(jù)進(jìn)行使用,我們把這樣的過(guò)程稱為遍歷,也叫迭代。

什么是可迭代對(duì)象

一個(gè)對(duì)象如果實(shí)現(xiàn)了__iter__方法(魔法方法),那么我們稱這個(gè)對(duì)象是可迭代對(duì)象。

或者可以這樣理解,只要是可以通過(guò)for…in…的形式進(jìn)行遍歷的,那么這個(gè)數(shù)據(jù)類型就是可以迭代的。

判斷數(shù)據(jù)是否可迭代

python中要判斷一個(gè)對(duì)象是否是可迭代的,可以用collections模塊中的Iterable來(lái)進(jìn)行判斷。isinstance函數(shù)會(huì)返回True或False來(lái)表明對(duì)象是(True)或者不是(False)可迭代對(duì)象。

from collections.abc import Iterable
print(isinstance(["abc"], Iterable))
print(isinstance([100], Iterable))

在這里插入圖片描述

什么是迭代器

迭代器的作用是用來(lái)訪問(wèn)容器(用來(lái)保存元素的數(shù)據(jù)結(jié)構(gòu))中的元素,所以使用迭代器,我們就可以訪問(wèn)容器中里面的元素。

迭代器是一個(gè)可以記住遍歷的位置的對(duì)象。迭代器對(duì)象從第一個(gè)元素開始訪問(wèn),直到所有的元素被訪問(wèn)完結(jié)束。迭代器只能往前不會(huì)后退。

迭代器的本質(zhì)

我們可以通過(guò)iter()函數(shù)獲取這些可迭代對(duì)象的迭代器。然后我們可以對(duì)獲取到的迭代器不斷使用next()函數(shù)來(lái)獲取下一條數(shù)據(jù)。

使用迭代器取數(shù)據(jù)

from collections.abc import Iterator
nums = [3, 6, 8]  # 可迭代對(duì)象
nums = iter(nums)  # 創(chuàng)建了迭代器
print("nums", isinstance(nums, Iterator))  # 判斷是否是迭代器
# 取出迭代器的數(shù)據(jù)
num1 = next(nums)
print(num1)
num1 = next(nums)
print(num1)
num1 = next(nums)
print(num1)

在這里插入圖片描述

若迭代的次數(shù)超過(guò)了可迭代對(duì)象的長(zhǎng)度, 就會(huì)報(bào)StopIteration異常。

自定義迭代器

使用__iter__和__next__方法自定義迭代器

只要在類中,定義__iter__方法,那么這個(gè)類創(chuàng)建出來(lái)的對(duì)象一定是可迭代對(duì)象

如果類中實(shí)現(xiàn)了__iter__方法和__next__方法的對(duì)象,就是迭代器。

當(dāng)我們調(diào)用iter()函數(shù)提取一個(gè)可迭代對(duì)象的 迭代器時(shí),實(shí)際上會(huì)自動(dòng)調(diào)用這個(gè)對(duì)象的__iter__方法,并且這個(gè)方法返回迭代器。

# 使用迭代器完成學(xué)生管理系統(tǒng)
class StuSystem(object):
    """
    學(xué)生管理系統(tǒng)
    """
    def __init__(self):
        self.stus = []
        self.current_num = 0
    def add(self):
        """
        添加一個(gè)新的學(xué)生
        :return:
        """
        name = input("請(qǐng)輸入新學(xué)生的姓名:")
        tel = input("請(qǐng)輸入新學(xué)生的手機(jī)號(hào):")
        address = input("請(qǐng)輸入新學(xué)生的住址:")
        new_stu = dict()
        new_stu["name"] = name
        new_stu["tel"] = tel
        new_stu["address"] = address
        self.stus.append(new_stu)
    def __iter__(self):
        return self
    def __next__(self):
        if self.current_num < len(self.stus):
            ret = self.stus[self.current_num]
            self.current_num += 1
            return ret
        else:
            self.current_num = 0
            raise StopIteration
# 創(chuàng)建對(duì)象
stu = StuSystem()
# 添加信息
stu.add()
stu.add()
stu.add()
stus = [x for x in stu]
print(stus)

在這里插入圖片描述

凡是可作用于for循環(huán)的對(duì)象都是Iterable 類型; 凡是可作用于 next() 函數(shù)的對(duì)象都是Iterator 類型; 集合數(shù)據(jù)類型如list 、dict、str等是 Iterable但不是Iterator,不過(guò)可以通過(guò) iter()函數(shù)獲得一個(gè)Iterator對(duì)象。

生成器

一邊循環(huán)一邊計(jì)算的機(jī)制,稱為生成器(generator)

在Python中,使用了yield的函數(shù)被稱為生成器。跟普通函數(shù)不同的是,生成器是一個(gè)返回迭代器的函數(shù),只能用于迭代操作。生成器函數(shù)一般是通過(guò)for循環(huán)調(diào)用,for循環(huán)自帶next方法。

創(chuàng)建生產(chǎn)器的方法

1.將列表推導(dǎo)式的[]改為()
2.在函數(shù)中使用yield關(guān)鍵字,函數(shù)就變成了一個(gè)generator

使用生成器完成斐波那契數(shù)列

def fib_generator():
    num1 = 1
    num2 = 1
    while True:
        temp_num = num1
        num1, num2 = num2, num1+num2
        # return temp_num  # 方式1代碼
        yield temp_num
# 方式1代碼(方式1不能夠生成1,1,2,3,5...斐波那契數(shù)列)
# print(fib_generator())
# print(fib_generator())
# print(fib_generator())
# print(fib_generator())
# 方式2代碼(可以生成斐波那契數(shù)列)
fib = fib_generator()
print(next(fib))
print(next(fib))
print(next(fib))
print(next(fib))

在這里插入圖片描述

關(guān)鍵字yield

yield是一個(gè)類似return的關(guān)鍵字。當(dāng)我們調(diào)用這個(gè)函數(shù)的時(shí)候并不是返回計(jì)算的結(jié)果。而是返回一個(gè)生成器。只有迭代這個(gè)生成器的時(shí)候才會(huì)計(jì)算結(jié)果。

next和send

next()方法: 在調(diào)用生成器運(yùn)行的過(guò)程中,每次遇到 yield ,函數(shù)返回當(dāng)前的值,并且會(huì)暫停并保存當(dāng)前所有的運(yùn)行信息, 并在下一次執(zhí)行 next() 方法時(shí)從當(dāng)前位置繼續(xù)運(yùn)行。

send()方法: 先理解個(gè)概念【休眠】:意思就是暫時(shí)保留先不進(jìn)行,等待需要時(shí)再進(jìn)行。作用與next()作用相似 區(qū)別:
1.send(value)可以傳遞value給yield,即:我們可以指定yield返回啥就返回啥,
2.next()不能傳遞特定的值,只能傳遞None進(jìn)去。

def genterator_test():
    while True:
        print("--1-")
        num = yield 100
        print("--2--", "num=", num)
g = genterator_test()
print(g.send(None))
print(g.send(11))
print(g.send(22))

在這里插入圖片描述

生成器的特點(diǎn): 存儲(chǔ)的是生成數(shù)據(jù)的方式(即算法),而不是存儲(chǔ)生成的數(shù)據(jù),因此節(jié)約內(nèi)存。

裝飾器

裝飾器是給現(xiàn)有的模塊增添新的小功能,可以對(duì)原函數(shù)進(jìn)行功能擴(kuò)展,而且還不需要修改原函數(shù)的內(nèi)容,也不需要修改原函數(shù)的調(diào)用。

裝飾器的功能

裝飾器的實(shí)現(xiàn)是由閉包支撐的; 裝飾器本質(zhì)上是?個(gè)python函數(shù),它可以在讓其他函數(shù)在不需要做任何代碼的變動(dòng)的前提下增加額外的功能; 裝飾器的返回值也是?個(gè)函數(shù)的對(duì)象,它經(jīng)常用于有切面需求的場(chǎng)景,實(shí)現(xiàn)路由傳參,flask的路由傳參依賴于裝飾器,瀏覽器通過(guò)url訪問(wèn)到裝飾器的路由,從而訪問(wèn)視圖函數(shù)獲得返回的HTML頁(yè)面;

定義裝飾器

def check_login(func):
    def inner():
        # 驗(yàn)證1
        # 驗(yàn)證2
        # 驗(yàn)證3
        func()
    return inner
@check_login
def f1():
    print('f1')
def check_login(func):
    def inner():
        # 驗(yàn)證1
        if "admin" != input("請(qǐng)輸入用戶名:"):
            return "用戶名不正確"
        # 驗(yàn)證2
        if "123456" != input("請(qǐng)輸入密碼:"):
            return "密碼不正確"
        # 驗(yàn)證3
        if "7788" != input("請(qǐng)輸入手機(jī)短信驗(yàn)證碼:"):
            return "驗(yàn)證碼不正確"
        func()
    return inner
@check_login
def f1():
    print('f1')
f1()  # 調(diào)用f1函數(shù)

閉包

什么是閉包

如果在一個(gè)內(nèi)部函數(shù)里,對(duì)在外部作用域(但不是在全局作用域)的變量進(jìn)行引用,那么內(nèi)部函數(shù)就被認(rèn)為是閉包(closure).

# 定義函數(shù)可以理解為:
# 定義了一個(gè)全局變量,其變量名字是函數(shù)的名字,即test
# 這個(gè)test變量指向了一個(gè)代碼塊,這個(gè)代碼塊是函數(shù)
# 其實(shí)就是說(shuō)test保存了一個(gè)代碼塊的地址,即引用
def test():
    print("--- in test func----")
test()  # 這是調(diào)用函數(shù)
ret = test # 用另外一個(gè)變量 復(fù)制了 test這個(gè)引用,導(dǎo)致ret變量也指向那個(gè) 函數(shù)代碼塊
# 下面輸出的2個(gè)地址信息是相同的
print(id(ret))
print(id(test))
# 通過(guò)引用調(diào)用函數(shù)
ret()

函數(shù)、匿名函數(shù)、閉包、對(duì)象 當(dāng)做實(shí)參時(shí)的區(qū)別

匿名函數(shù)能夠完成基本的簡(jiǎn)單功能,,,傳遞是這個(gè)函數(shù)的引用 只有功能
普通函數(shù)能夠完成較為復(fù)雜的功能,,,傳遞是這個(gè)函數(shù)的引用 只有功能
閉包能夠?qū)⑤^為復(fù)雜的功能,,,傳遞是這個(gè)閉包中的函數(shù)以及數(shù)據(jù),因此傳遞是功能+數(shù)據(jù)
對(duì)象能夠完成最為復(fù)雜的功能,,,傳遞是很多數(shù)據(jù)+很多功能,因此傳遞是功能+數(shù)據(jù)

到此這篇關(guān)于詳解Python中的三器一閉的文章就介紹到這了,更多相關(guān)Python三器一閉內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論