裝飾器的補充以及迭代器

裝飾器的補充以及迭代器

1、登陸認證功能

user_info = {
    'user': None
}
#登陸功能認證
def login():
    username = input('請輸入帳號名:').strip()
    password = input('請輸入密碼:').strip()
    with open(r'a.txt', 'r', encoding='utf-8')as f:
        for line in f:
            f.readline()
            name, pwd = line.strip('\n').split(':')#交叉賦值返回的是['yafeng','666']
    if username == name and password == pwd:
        print('登陸成功!')
        user_info['user'] = username
    else:
        print('登陸失敗!')

def login_auth(func):

    def inner(*args, **kwargs):
        #已經登陸,將被裝飾對象直接調用並返回
        if user_info.get('user'):#若是在列表裏
            res = func(*args, **kwargs)

            return res
        else:
            print('請先登陸')
            login()
            '''
            注意: 不管inner中出現任何判斷,
            最後都要返回「調用後的被裝飾對象」 func(*args, **kwargs)
             '''
            res = func(*args, **kwargs)#注意此時必定要返回res,不然from 1 打印不出來
            return res

    return inner


@login_auth
def func1():
    print('from 1')
    pass

@login_auth
def func2():
    print('from 2')
    pass
@login_auth
def func3():
    print('from 3')
    pass

while True:
    func1()
    input('請輸入操做')
    func2()
    func3()

2、裝飾器之疊加裝飾器

有的時候咱們想要對一個被裝飾函數進行多功能的裝飾,雖然咱們也能夠在一個裝飾器中去添加多個功能,但這樣就會顯得代碼很長,可讀性不高,並且若是之後咱們又想修改這個裝飾器函數的功能,咱們還得去刪除,咱們最好的方法就是一個裝飾器就固定哪個功能,咱們想要對函數進行多此裝飾,那麼此時疊加裝飾器就派上用場了。python

  • 疊加裝飾器
在同一個被裝飾對象中,添加多個裝飾器,並執行。
@裝飾1
@裝飾2
@裝飾3
def 被裝飾對象():
    pass

注意:疊加裝飾器的順序*****(重要)
    裝飾的順序:由下到上裝飾
    執行的順序:由上往下
  • 疊加器演示
def wrapper1(func):
    def inner1(*args, **kwargs):
        print('1---start')
        # 被裝飾對象在調用時,若是還有其餘裝飾器,會先執行其餘裝飾器中的inner
        # inner2
        res = func(*args, **kwargs)
        print('1---end')
        return res

    return inner1


def wrapper2(func):
    def inner2(*args, **kwargs):
        print('2---start')
        res = func(*args, **kwargs)
        print('2---end')
        return res

    return inner2


def wrapper3(func):
    def inner3(*args, **kwargs):
        print('3---start')
        res = func(*args, **kwargs)
        print('3---end')
        return res

    return inner3


'''
疊加裝飾器的裝飾順序與執行順序:
    - 裝飾順序: 調用wrapper裝飾器拿到返回值inner
        由下往上裝飾

    - 執行順序: 調用裝飾事後的返回值inner
        由上往下執行
'''


@wrapper1  # index《---inner1 = wrapper1(inner2)
@wrapper2  # inner2 = wrapper2(inner3)
@wrapper3  # inner3 = wrapper3(index)
def index():  # 被裝飾對象   # inner1 ---》
    print('from index...')


# 正在裝飾
inner3 = wrapper3(index)
inner2 = wrapper2(inner3)
inner1 = wrapper1(inner2)

'''
inner1()
inner2()
inner3()
index()
'''
index()  # 此處執行 # inner1() --> inner2() ---> inner3()
>>>1---start
2---start
3---start
from index...
3---end
2---end
1---end
  • 有參裝飾器

以前咱們用的都是無參裝飾器,就是在裝飾被裝飾對象時,沒有傳參app

'''
# 如下是無參裝飾器
@wrapper1  # inner1 = wrapper1(inner2)
@wrapper2  # inner2 = wrapper2(inner3)
@wrapper3
'''

# 有參裝飾器: 在某些時候,咱們須要給用戶的權限進行分類
'''
# 如下是有參裝飾器
@wrapper1(參數1)  # inner1 = wrapper1(inner2)
@wrapper2(參數2)  # inner2 = wrapper2(inner3)
@wrapper3(參數3)
'''
  • 有參裝飾器
def user_auth(user_role):  # 'SVIP'
    def wrapper(func):
        def inner(*args, **kwargs):
            if user_role == 'SVIP':
                # 添加超級用戶的功能
                res = func(*args, **kwargs)
                return res
            elif user_role == '普通用戶':
                print('普通用戶')
                # 添加普通用戶的功能
                res = func(*args, **kwargs)
                return res

        return inner
    return wrapper


# 被裝飾對象
# @user_auth('SVIP')
wrapper = user_auth('普通用戶')
@wrapper
# @user_auth('SVIP')  # wrapper = user_auth('普通用戶')
@wrapper  #<--- 返回結果(wrapper) <---- user_auth()
def index():
    pass
index()
  • wraps
'''
wraps: (瞭解)
    是一個修復工具,修復的是被裝飾對象的空間。
    from functools import wraps

'''
from functools import wraps


def wrapper(func):

    @wraps(func)  # 修更名稱空間: inner ---》 func
    def inner(*args, **kwargs):
        '''
        此處是裝飾器的註釋
        :param func:
        :return:
        '''
        res = func(*args, **kwargs)
        return res
    return inner  # ---》 func


@wrapper
def index():
    '''
    此處是index函數的註釋
    :return:
    '''
    pass


print(index)  # 函數對象

# 函數對象.__doc__: 查看函數內部的註釋
print(index.__doc__)  # inner.__doc__

3、迭代器

  • 什麼是迭代器

迭代:迭代是一個重複的過程,而且每次重複都是基於上一次的結果而來函數

x = 10
while True:
    print(x)
#這雖然是重複過程,但並無基於上一次的結果

l = [1,2,3,4]
n = 0
while n < len(l):
    print(l[n])
    n  += 1
>>>1
2
3
4
#這纔是一個迭代,每次結果基於上一次

要想了解迭代,咱們還得先了解什麼是可迭代對象工具

在python中,但凡內置有._iter_()方法的對象都叫可迭代對象因此如下都是可迭代對象:
str
list
dict
tuple
set
file

瞭解了什麼是可迭代對象的概念後咱們就能夠給迭代器下定義了,迭代器指的是更新取值的工具。code

知道了什麼是迭代器,什麼是可迭代對象之後,咱們就能夠去說什麼是迭代器對象對象

迭代器對象:索引

可迭代的對象執行._iter_()方法獲得的返回值就是迭代器對象,接下來咱們在用獲得的迭代器對象.__next__()就能夠去獲取每一個元素的值了ip

s = {1, 2, 3}
iter_s = s.__iter__()#iter_s就是迭代器對象
print(iter_s.__next__())
print(iter_s.__next__())
print(iter_s.__next__())
print(iter_s.__next__())
>>>Traceback (most recent call last):
  File "D:/python的pycharm/正式課/day12/迭代器.py", line 53, in <module>
    print(iter_s.__next__())
StopIteration
1
2
3

上面咱們雖然拿到了每一個集合中的元素,但會報錯,就是有個StopIteration的錯誤,該錯誤指的是當我打印的值超過了個人一個容器中的全部容量的時候會報錯,由於已經沒有對象讓咱們訪問了,那此時咱們能不能即能獲取到裏面的全部元素,也不報錯呢,答案是確定的。這時就須要用到try內存

s = {1, 2, 3}
iter_s = s.__iter__()#iter_s就是迭代器對象
while True:
    try:
        print(iter_s.__next__())

    except StopIteration:
        break
>>>1
2
3
  • 總結比比較utf-8

    可迭代的對象:

    ​ 特色:內置有——iter——方法的,就都是可迭代的對象,執行該方法會獲得一個迭代器對象

    迭代器對象的特色:

    ​ 內置有——next——方法,每一次執行會拿到迭代器對象中的一個值

    ​ 內置有——iter——方法,執行會獲得迭代器自己

    迭代器的特色:

    ​ 優勢:提供了一種不依賴於索引取值的方法

    ​ 迭代器會更加節省空間內存

    ​ 缺點:取值麻煩,只能一個一個取

    ​ 沒法使用len去獲取某個具體的值

相關文章
相關標籤/搜索