码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2017-12-08 22:58:06      阅读:227      评论:0      收藏:0      [点我收藏+]

标签:login   success   分享   问题   一个   type   home   isp   pen   

一、装饰器

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-之装饰器、迭代器、生成器

标签:login   success   分享   问题   一个   type   home   isp   pen   

原文地址:http://www.cnblogs.com/xiechao621/p/8007179.html

踩
(0)
赞
(0)
   
举报
评论 一句话评论(0)
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!