python函数(3):装饰器

昨天学了很多函数方面的概念和知识其中有一个闭包的函数。很多人都对闭包的作用不是很清楚,今天我们就来认识一个新的知识点装饰器。它就是闭包函数的一个经典应用。

预习:

编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码

一、楔子

def func1():
    print(‘in func1‘)

想要计算上面函数的执行时间:

import time
def func1():
    start = time.time()
    print(‘in func1‘)
    end =print(time.time() - end) func1()

可是如果你要计算你写过的所有函数的执行时间就要挨个去改代码。写个函数可不可以:

import time
def timer(func):
    start = time.time()
    func()
    print(time.time() - start)

def func1():
    print(‘in func1‘)

def func2():
    print(‘in func2‘)

timer(func1)
timer(func2)

不管我们写了多少个函数都可以调用这个计时函数来计算函数的执行时间了。。。尽管现在修改成本已经变得很小很小了,但是还是改变了这个函数的调用方式,如果有很多函数还是要改很多

你要做的就是,让你的同事依然调用func1,但是能实现调用timer方法的效果

import time
def timer(func):
    start = time.time()
    func()
    print(time.time() - start)

def func1():
    print(‘in func1‘)

func1 =timer(func1)  #报错
func1()

非常可惜,上面这段代码是会报错的,因为timer方法需要传递一个func参数,我们不能在赋值的时候传参,因为只要执行func1 = timer(func1),timer方法就直接执行了,下面的那句func1根本就没有意义。



二、装饰器的形成

器即函数

装饰即修饰,意指为其他函数添加新功能

装饰器定义:本质就是函数,功能是为其他函数添加新功能

import time

def func1():
    print(‘in func1‘)

def timer(func):
    def inner():
        start = time.time()
        func()
        print(time.time() - start)
    return inner

func1 = timer(func1)
func1()

装饰器——简单版1

现在唯一麻烦就是还要在做一次赋值调用。。。python的开发者也觉得碍眼,所以就为我们提供了一句语法糖来解决这个问题!

import time
def timer(func):
    def inner():
        start = time.time()
        func()
        print(time.time() - start)
    return inner

@timer   #==> func1 = timer(func1)
def func1():
    print(‘in func1‘)

func1()

装饰器——语法糖

到这里,我们可以简单的总结一下:

装饰器的本质:一个闭包函数

装饰器的功能:在不修改原函数及其调用方式的情况下对原函数功能进行扩展

最后一个问题要解决,刚刚我们讨论的装饰器都是装饰不带参数的函数,现在要装饰一个带参数的函数怎么办

def timer(func):
    def inner(a):
        start = time.time()
        func(a)
        print(time.time() - start)
    return inner

@timer
def func1(a):
    print(a)

func1(1)

装饰器——带参数的装饰器

假如你有两个函数,需要传递的参数不一样

import time
def timer(func):
    def inner(*args,**kwargs):
        start = time.time()
        re = func(*args,**kwargs)
        print(time.time() - start)
        return re
    return inner

@timer   #==> func1 = timer(func1)
def func1(a,b):
    print(‘in func1‘)

@timer   #==> func2 = timer(func2)
def func2(a):
    print(‘in func2 and get a:%s‘%(a))
    return ‘fun2 over‘

func1(‘aaaaaa‘,‘bbbbbb‘)
print(func2(‘aaaaaa‘))

装饰器—万能装饰器

如果你的函数是有返回值的

import time
def timer(func):
    def inner(*args,**kwargs):
        start = time.time()
        re = func(*args,**kwargs)
        print(time.time() - start)
        return re
    return inner

@timer   #==> func2 = timer(func2)
def func2(a):
    print(‘in func2 and get a:%s‘%(a))
    return ‘fun2 over‘

func2(‘aaaaaa‘,‘bbbbbb‘)
print(func2(‘aaaaaa‘))

装饰器—带返回值的装饰器



三、开放封闭原则

1、对扩展是开放的

我们说,任何一个程序,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改。所以我们必须允许代码扩展、添加新功能。

2、对修改是封闭的

就像我们刚刚提到的,因为我们写的一个函数,很有可能已经交付给其他人使用了,如果这个时候我们对其进行了修改,很有可能影响其他已经在使用该函数的用户。

装饰器完美的遵循了这个开放封闭原则。



四、装饰器的主要功能和装饰器的固定结构

装饰器的主要功能:

在不改变函数调用方式的基础上在函数的前、后添加功能。

装饰器的固定格式:

def timer(func):
    def inner(*args,**kwargs):
        ‘‘‘执行函数之前要做的‘‘‘
        re = func(*args,**kwargs)
        ‘‘‘执行函数之后要做的‘‘‘
        return re
    return inner

装饰器的固定格式



五、带参数的装饰器

未完待续



预习解答:

#编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,
#后续的函数都无需再输入用户名和密码
# tag = True
tag = [True]
def rz(func) :
    def inner() :
        # global tag
        # while tag :
        while tag[0] :
            name = input("please input your name:").strip()
            passworld = input("please input your passworld:").strip()
            with open("demo.py", ‘r‘, encoding=‘utf-8‘) as read_f :
                print()
                if read_f.readline() == name+"\n" and read_f.readline() == passworld+"\n" :
                    # tag = False
                    tag[0] = False
        func()
    return inner

@rz
def func() :
    print("lln")
@rz
def func1() :
    print("lln1")
@rz
def func2() :
    print("lln2")

func()
func1()
func2()

预习答案

时间: 2024-11-02 23:34:51

python函数(3):装饰器的相关文章

python函数、装饰器、迭代器、生成器

5月21日,请假结婚,然后性格惰性来了,不怎么想看视频和笔记,性格中的弱点开始出现,开始做的不错,渐渐开始松懈,直至放弃--- 函数补充进阶 函数对象 函数的嵌套 名称空间与作用域 闭包函数 函数之装饰器 函数之迭代器 函数之生成器 内置函数 一.函数补充进阶 1.函数对象:  函数是第一类对象,即函数可以当作数据传递,它的应用形式也被称为高阶函数,函数的特性如下: a. 可以被引用 1 # def foo(): 2 # print('from foo') 3 # 4 # func = foo

五、python函数、装饰器、内置函数、json及模块

一.递归调用 1.一个函数自己调用自己就是递归调用,最多一个函数递归调用自己999次,超过就会出错2.递归必须有一个明确的结束条件3.每次进入更深一层递归时,问题规模相比上次递归都应有所减少4.递归效率不高,少用递归 eg:def test1(): num = int(input('please enter a number:')) if num%2==0:#判断输入的数字是不是偶数 return True #如果是偶数的话,程序就退出了,返回true print('不是偶数请重新输入!') r

Python函数之装饰器

装饰器 一.装饰器的意义 比如:以下函数是供我们调用的,但是我们需要在每个函数中都添加同一个功能,该如何做到呢? 对于函数开放封闭原则,我们一般不允许修改.所以我们引入了装饰器: def outer(func): def inner(): print("添加在原函数之前") r = func() #保留原函数的返回值 print('添加在原函数之后') return r #将保留的返回值返回回去 return inner @outer #等价于f1 = outer(f1) def f1

Python函数加工厂-装饰器

引言: 函数和装饰器好比程序界的加工厂: 1.函数一般可用来加工一种或者多种数据类型的数据:字符串.数字.列表.字典等 举一个简单例子:已知半径求面积 def s(r): s = 3.14 * r * r return s 调用s函数:输入4,输出半径为4的圆的面积.a相当于面积的容器 a = s(4) print(a) 2.装饰器是用来装饰函数的函数.其需要输入的原材料为某个函数 以下是装饰器的固定格式: 1 def timer(func): 2 def inner(*args,**kwarg

python函数作用域+装饰器

今天记录的是一个小小的知识点 ->函数作用域+装饰器: LEGB:L>E>G>B L;local函数内部作用域 E:enclosing函数内部与内嵌函数之间 G:global全局作用域 B:build-in内置作用域 Coding && Result: 闭包(Closure):内部函数中对enclosing作用域的变量进行引用. 闭包的作用: 1)封装 2)代码复用 函数的实质和属性: 1)函数是一个对象 2)函数执行完成之后内部变量回收 3)函数是对象就有属性 4

Learn Python—函数(装饰器)

装饰器 开放封闭原则 开放:对函数的扩展是开放的 封闭:对函数的修改是封闭的 装饰器的作用 在不更改原函数调用方式的前提下,对原函数添加新功能 # ①引子--为什么要有装饰器 为了在不修改原函数的基础上为函数添加新功能,产生了装饰器 # ②简单装饰器 def deco(f): def wrapper(): """原函数前添加的功能""" f() """原函数后添加的功能""" retur

python函数_装饰器

理解: 装饰器:我在知乎看到这样一个比方(我们的函数好比内裤,作用是遮羞.但在一些特定的环境,内裤明显满足不了我们的需求,冬天它没法为我们防风御寒.所以有了长裤,装饰器就像长裤,在不影响内裤作用的前提下,给我们的身子提供了保暖的功效) 装饰器是对原函数的一种扩展,本质是一个python函数,在原函数不需要做任何代码变动的前提下增加额外功能,在场景:插入日志.性能测试.事务处理.权限校验等应用广泛.遵守封闭开放原则,对源代码修改封闭,对功能外部增加开放. 需求: 在电商平台中,我们可以看到,在不同

python函数下篇装饰器和闭包,外加作用域

装饰器和闭包的基础概念 装饰器是一种设计模式能实现代码重用,经常用于查日志,性能测试,事务处理等,抽离函数大量不必的功能. 装饰器:1.装饰器本身是一个函数,用于装饰其它函数:2.功能:增强被装饰函数的功能. 装饰器需要遵循的原则 1.不修改被装饰函数的源代码(开放封闭原则) 2.为被装饰函数添加新功能后,不修改被装饰函数的调用方式 装饰器 = 高阶函数+函数嵌套+闭包 高阶函数 1.函数接受的参数是一个函数名 2.函数的返回值是一个函数名 3.只有上述条件满足一个就是高阶函数 def foo(

Python函数(八)-装饰器(一)

装饰器通过函数来定义,用来装饰函数 装饰器不改变被装饰函数的源代码和运行方式 如何实现这个效果呢? # -*- coding:utf-8 -*- __author__ = "MuT6 Sch01aR" import time def timer(func): #定义一个装饰器 def deco(): start_time = time.time() func() stop_time = time.time() print("the run time is %s"%(

doraemon的python 函数与装饰器(哎呀,忘记传了)

5.10 函数中高级 5.10.1 函数可以当做返回值 def func():    print(123)    def bar():    return func?v = bar()?v() 5.10.2 闭包 def func(name):    def innner():        print(name)    return inner?v1 = func('liujia')v1()v2 = func('eric')v2() 总结: 函数执行的流程分析(函数式谁创建的) 闭包概念:为函