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‘)

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__)

  

时间: 2024-08-02 01:49:20

python-之装饰器、迭代器、生成器的相关文章

Python学习---装饰器/迭代器/生成器的学习【all】

Python学习---装饰器的学习1210 Python学习---生成器的学习1210 Python学习---迭代器学习1210 原文地址:https://www.cnblogs.com/ftl1012/p/9484145.html

函数嵌套 ,名称空间与作用域 ,闭包函数 ,装饰器 ,迭代器, 生成器 三元表达式,列表解析,生成器表达式 递归与二分法, 内置函数

函数嵌套名称空间与作用域闭包函数装饰器迭代器生成器三元表达式,列表解析,生成器表达式递归与二分法内置函数--------------------------------------------函数的嵌套调用:在调用一个函数的过程中,又调用了其他函数函数的嵌套定义:在一个函数的内部,又定义另外一个函数def max(x,y): if x>y: return x else: return ydef max1(a,b,c,d): res=max(a,b) res2=max(res,c) res3=ma

python_day04 函数嵌套 名称空间和作用域 闭包 装饰器 迭代器 生成器 列表解析 三元表达式 生成器表达式

本节课重要知识点内容如下: 函数嵌套 名称空间和作用域 闭包 装饰器 迭代器 生成器 列表解析 三元表达式 生成器表达式 1.函数嵌套 函数的嵌套调用:在调用一个函数的过程中,又调用了其他函数函数的嵌套定义:在一个函数的内部,又定义另外一个函数 def bar(): print('from nbar')def foo(): print('from foo') bar()foo()def max2(x,y): if x > y: return x else: return ydef max4(a,

python学习--装饰器、生成器、内置函数、json

这周学习了装饰器和生成器,写下博客,记录一下装饰器和生成器相关的内容. 一.装饰器 装饰器,这个器就是函数的意思,连起来,就是装饰函数,装饰器本身也是一个函数,它的作用是用来给其他函数添加新功能,比如说,我以前写了很多代码,系统已经上线了,但是性能比较不好,现在想把程序里面每个函数都加一个功能,用来统计每个函数的运行时间是多少,找出来运行比较慢的函数,来优化代码,就需要添加一个新的功能,来统计程序的运行时间,那这样的话,就得修改每个函数了,需要改代码,但是代码特别多,改完了公司倒闭了,这时候装饰

Python之路-python(装饰器、生成器、迭代器、Json & pickle 数据序列化、软件目录结构规范)

装饰器: 首先来认识一下python函数, 定义:本质是函数(功能是装饰其它函数),为其它函数添加附件功能        原则:        1.不能修改被装饰的函数的源代码.        2.不能修改被装饰的函数的调用方式. 1 def test(): 2 print('test') 3 print(test ) #表示是函数 4 test() #表示执行foo函数 <function test at 0x00595660>#表示的是函数的内存地址test#函数test执行结果 简单的装

python第四天装饰器+迭代器+生成器

1.函数嵌套:在调用一个函数的过程中,调用了其他函数 def f1(): x=1 def f2(): print('from f2') f2() f1()  2.名称空间与作用域 a. 名称空间:存放名字与变量值绑定关系的地方 (1)内置名称空间:在python解释器启动时产生,存放一些python内置的名字 (2)全局名称空间:在执行文件时产生,存放文件级别定义的名字. (3)局部名称空间:在执行过程中,如果调用了该函数则会产生该函数的局部名称空间.在调用该函数的时候生效,调用结束时失效 加载

&lt;04day&gt;_函数嵌套--闭包函数--装饰器--迭代器--生成器

一.函数的嵌套定义 1.python函数支持嵌套 def f1(): #f1函数的定义 def f2(): #f2函数的定义 print('from f2') def f3(): #f3函数的定义 print('from f3') f2() f1() 嵌套函数--运行结果说明: 1首先调用f1()结果,f1函数为空.担保函f2函数,f2函数有内容打印并且有调用,f2函数包含f3函数,但f3函数无调用. 运行结果: 列子:多个数据之间的大小比较. #!/usr/bin/python # -*- c

函数+装饰器+迭代器+生成器

闭包函数 闭包:定义在内网函数,包含对外部作用域而非全局作用域 范围:一个函数套用1或n个函数 from urllib.request import urlopen #urlopen模块 作用:爬网页 #闭包函数,内部get函数调用外部page函数 def page(url): #调用url def get(): #下载 return urlopen(url).read() #爬网页 return get #返回url值 baidu=page("http://www.baidu.com"

Day4 装饰器——迭代器——生成器

一 装饰器 1.1 函数对象 一 函数是第一类对象,即函数可以当作数据传递 #1 可以被引用 #2 可以当作参数传递 #3 返回值可以是函数 #3 可以当作容器类型的元素 二 利用该特性,优雅的取代多分支的if def foo(): print('foo') def bar(): print('bar') dic={ 'foo':foo, 'bar':bar, } while True: choice=input('>>: ').strip() if choice in dic: dic[ch

day-5 装饰器 迭代器 生成器

1.装饰器 1.1 带参数的装饰器 参数可以用来决定是否执行某个装饰器的某一部分 def outer(flag): def timer(func): def inner(*args,**kwargs): if flag: print('''执行函数之前要做的''') re = func(*args,**kwargs) if flag: print('''执行函数之后要做的''') return re return inner return timer @outer(False) def func