python-之装饰器迭代器生成器

Posted xiechao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python-之装饰器迭代器生成器相关的知识,希望对你有一定的参考价值。

一、装饰器

1、为何要用装饰器

#开放封闭原则:对修改封闭,对扩展开放

2、 什么是装饰器

装饰器他人的器具,本身可以是任意可调用对象,被装饰者也可以是任意可调用对象。
强调装饰器的原则:1 不修改被装饰对象的源代码 2 不修改被装饰对象的调用方式
装饰器的目标:在遵循1和2的前提下,为被装饰对象添加上新功能
技术分享图片
import time


def index():
    time.sleep(3)
    print(welcome to index)


# index()

def wrapper(func):
    start_time = time.time()
    func()
    stop_time = time.time()
    print(run time is %s % (stop_time - start_time))


wrapper(index)


# ================闭包实现=============================
import time


def index():
    time.sleep(3)
    print(welcome to index)


def timmer():
    func = index  # 这么写严格收到层级限制了,内部的函数无法调取,需要return返回值

    def wrapper():  # 注意这里,func已经定义了等于index,就不需要写默认参数了
        start_time = time.time()
        func()
        stop_time = time.time()
        print(run time is %s % (stop_time - start_time))

    return wrapper


# wrapper=timmer()       #运行timmer,得到的结果是wrapper,并且把值赋给了wrapper
# wrapper()

index = timmer()  # 如上,既然可以把timmer运行的返回值赋值给warpper,那么同理也可以赋值给index
index()

####这么写没有修改源代码,也没有修改调用方式,也加上的新功能。实现了装饰器
####这么写其实是有问题的,如果又来了一个函数。这种闭包就无法实现了。解决方法如下
# ==============================================

import time


def index():
    time.sleep(3)
    print(welcome to index)


def home():
    time.sleep(2)
    print(welcome to home page)


# index()
def timmer(func):
    # func=index
    def wrapper():  # 注意这里,func已经定义了等于index,就不需要写默认参数了
        start_time = time.time()
        func()
        stop_time = time.time()
        print(run time is %s % (stop_time - start_time))

    return wrapper


index = timmer(index)  # 给func一个index的值,最后返回的值是wrapper,我可以把它赋值给index,home同理
home = timmer(home)
index()
home()

# =================装饰器=======================




import time



def timmer(func):
    # func=index
    def wrapper():
        start = time.time()
        func()
        stop = time.time()
        print(run time is %s % (stop - start))

    return wrapper


@timmer  # index=timmer(index)   自上而下运行,代表调用timmer 并且给timmer传值为index
def index():
    time.sleep(3)
    print(welcome to index)


@timmer # home=timmer(home)
def home():
    time.sleep(2)
    print(welcome to home page)

index()
home()



# =================被装饰器是有参函数=======================


import time



def timmer(func):
    # func=index
    def wrapper(name):
        start = time.time()
        func(name)
        stop = time.time()
        print(run time is %s % (stop - start))

    return wrapper


@timmer  # home=timmer(home)
def home(name):
    time.sleep(2)
    print(welcome %s home  % (home))


home(egon)


# ===========有参和无参混合用=======================
import time



def timmer(func):
    # func=index
    def wrapper(*args, **kwargs):  # 闭包函数适应有参无参,各种* 传参的方式
        start = time.time()
        func(*args, **kwargs)
        stop = time.time()
        print(run time is %s % (stop - start))

    return wrapper


@timmer  # index=timmer(index)   自上而下运行,代表调用timmer 并且给timmer传值为index
def index():
    time.sleep(3)
    print(welcome to index)


@timmer  # home=timmer(home)
def home(name):
    time.sleep(2)
    print(welcome %s to home  % (name))


index()
home(agon)
View Code
技术分享图片
import time


def timmer(func):
    def wrapper(*args, **kwargs):
        start = time.time()
        res = func(*args, **kwargs)

        stop = time.time()
        print(run time is %s % (stop - start))
        return res

    return wrapper


@timmer  # index=timmer(index)
def index():
    time.sleep(3)
    print(welcome to index)
    return 123


@timmer  # home=timmer(home)
def home(name):
    time.sleep(2)
    print(welcome %s to home page % name)


# res=index() #res=wrapper()
# print(res)

res1 = home(egon)  # wrapper(‘egon‘)
print(res1)
装饰器返回值

3、装饰器的使用

技术分享图片
import time
def timmer(func):
    def wrapper(*args,**kwargs):
        start_time=time.time()
        res=func(*args,**kwargs)
        stop_time=time.time()
        print(run time is %s %(stop_time-start_time))
        return res
    return wrapper

@timmer
def foo():
    time.sleep(3)
    print(from foo)
foo()
无参装饰器
技术分享图片
def auth(driver=file):
    def auth2(func):
        def wrapper(*args,**kwargs):
            name=input("user: ")
            pwd=input("pwd: ")

            if driver == file:
                if name == egon and pwd == 123:
                    print(login successful)
                    res=func(*args,**kwargs)
                    return res
            elif driver == ldap:
                print(ldap)
        return wrapper
    return auth2

@auth(driver=file)
def foo(name):
    print(name)

foo(egon)
有参装饰器

4、装饰器语法

被装饰函数的正上方,单独一行
        @deco1
        @deco2
        @deco3
        def foo():
            pass

        foo=deco1(deco2(deco3(foo)))

5、加认证功能的装饰器

技术分享图片
current_user = {user: None}


def auth(func):
    def wrapper(*args, **kwargs):
        if current_user[user]:
            return func(*args, **kwargs)

        name = input(name: ).strip()
        password = input(password: ).strip()

        with open(db.txt, encoding=utf-8) as f:
            user_dic = eval(f.read())
        if name in user_dic and password == user_dic[name]:
            res = func(*args, **kwargs)
            current_user[user] = name
            return res
        else:
            print(user or password error)

    return wrapper


@auth  # index=auth(index) index=wrapper
def index():
    print(from index)


index()


@auth
def home(name):
    print(welcome %s % name)


index()  # wrapper()
home(egon)
无参版本
技术分享图片
current_user = {user: None}


def auth(auth_type=file):
    def deco(func):
        def wrapper(*args, **kwargs):
            if auth_type == file:
                if current_user[user]:
                    return func(*args, **kwargs)
                name = input(name: ).strip()
                password = input(password: ).strip()

                with open(db.txt, encoding=utf-8) as f:
                    user_dic = eval(f.read())
                if name in user_dic and password == user_dic[name]:
                    res = func(*args, **kwargs)
                    current_user[user] = name
                    return res
                else:
                    print(user or password error)
            elif auth_type == mysql:
                print(mysql)

            elif auth_type == ldap:
                print(ldap)
            else:
                print(not valid auth_type)

        return wrapper

    return deco


@auth(auth_type=mysql)  # @deco  #index=deco(index)
def index():
    print(from index)


@auth(auth_type=file)
def home(name):
    print(welcome %s % name)


index()  # wrapper()
home(egon)
有参版本

6、装饰器补充:wraps  

from functools import wraps

def deco(func):
    @wraps(func) #加在最内层函数正上方
    def wrapper(*args,**kwargs):
        return func(*args,**kwargs)
    return wrapper

@deco
def index():
    ‘‘‘哈哈哈哈‘‘‘
    print(‘from index‘)

print(index.__doc__)

  

 

以上是关于python-之装饰器迭代器生成器的主要内容,如果未能解决你的问题,请参考以下文章

python-之装饰器迭代器生成器

python的重重之器(生成器迭代器装饰器)

Python之迭代器,生成器与装饰器

Python之装饰器迭代器和生成器

Python之迭代器生成器装饰器和递归

Python--核心2(生成器,迭代器,闭包,装饰器)之生成器