Python入门之函数的装饰器

本章目录:

    装饰器:

        一、为什么要用装饰器

        二、什么是装饰器

        三、无参装饰器

        四、装饰器语法糖

        五、认证装饰器实现

        六、叠加多个装饰器

        七、带参装饰器   

===========================================================

一、开放封闭原则

  引子--为什么要用装饰器

  软件一旦上线后,对修改源代码是封闭的,对功能扩展是开放的。

  也就是说我们必须找到一种解决方案:

    能够在不修改一个功能源代码以及调用方式的前提下,为其加上新功能

    

    总结,原则如下:

      1、不修改源代码

      2、不修改调用方式

    目的:

      在原则1&2的基础上扩展新功能

二、什么是装饰器

  装饰器(Decorator)是一种特殊的函数,用来给函数添上新功能的函数。

  主要用于抽离大量函数中与函数本身无关的雷同代码并继续重用。

  装饰器又可分为带参数和不带参数。

  完整含义:

  装饰器即在不修改被装饰对象源代码与调用方式的前提下,为被装饰器对象添加新功能

  装饰器与被装饰对象均可以是任意可调用的对象

  装饰器>>>函数

  被装饰的对象>>>函数

三、装饰器实现之无参装饰器

  装饰器的实现不能脱离,不能修改源代码,不能修改源调用方式的原则。下面我们将按照实现装饰器的思路,一步一步实现装饰器。

  为下面的程序增加运行计时功能。

import time

def index():

   time.sleep()
   print(‘This is Index Page!‘)    

  方案1:

import time

def index():
    start_time=time.time()
    time.sleep(3)
    print(‘welcome to index page‘)
    stop_time=time.time()
    print(‘run time is %s‘ %(stop_time-start_time))

index()
# 该方案虽然达到了计时功能,但是修改了源代码,违背了装饰器两大原则

  方案2:

import time   #引入时间包,方便调用time()方法

def index():
    time.sleep(2)
    print(‘This is Index Page.‘)

start_time = time.time()
index()
stop_time = time.time()
print(‘The running time is %s‘ % (stop_time - start_time)
# 该方案虽然达到了计时功能,但是只是针对的增加代码,如果别的程序也要计时,还要重写一次,无法复用。

  方案3:

import time

def index():
    time.sleep(2)
    print(‘This is Index Page‘)

def wrapper():
  start_time = time.time()
  index()
  stop_time = time.time()
  print(‘The running time is %s‘ % (stop_time - start_time)) 
# 该方案虽然达到了计时功能,但是要显示计时,还要去调用wrapper(),更改了原函数的调用方式

  方案4:

import time

def index():
    time.sleep(2)
    print(‘This is Index Page‘)

def wrapper(func):    #func = index

    start_time = time.time()
    func();      #index
    stop_time = time.time()
    print(‘The running time is %s‘ % (stop_time, start_time))

wrapper(index)
# 该方案虽然达到了计时功能,但是要显示计时,不仅要调用wrapper(), 而且需要把原函数index作为参数导入,更改了原函数的调用方式

  方案5(步入正轨之无参装饰器):

import time

def index():
    time.sleep()
    print(‘This is Index Page‘)

def outter(func):     # func = 最初始的index
                      # func = index    巧用闭包,传递参数,
                      # 外部函数带的参数,就是准备给内部函数里用的,这里是闭包功能
    def wrapper():
        start_time = time.time()
        func()
        stop_time = time.time()
        print(‘The running time is %s‘)
    return wrapper

index = outter(index)   #初始index函数经过处理已经被变更为outter(index),被‘‘装饰‘‘了

index()
# 该方法能显示运行时长, 是把最初始的index函数通过闭包的特点,经过处理后重新把新的函数内存地址,赋值给了index,后面的index函数已经不是最初的index,它经过被‘‘装饰‘‘了

  方案6(方案5的升级版):

    1. 无参装饰器,引入带参函数的时候出现了错误。

# 不同于index()函数,这次我们引入一个新函数,带参数call_you(name)
import time

def call_you(name):
    time.sleep(2)
    print(‘I call you %s‘ %name)

def outter(func):

    def wrapper(name):
        start_time = time.time()
        res = func(name)
        stop_time = time.time()
        print(‘The running time is %s‘ % (stop_time - start_time)
        return res

    return wrapper

index = outter(index)
home = outter(home)  #home带参,但是index不带参,这里运行会报错

  方案7(解决方案6的问题):

# 运用可变长度参数处理这个问题
# 可变长度参数模版,注意参数是*args  **kwargs

def outter(func):

    def inner(*args, **kwargs):
        res = func(*args, ** kwargs)
        return res

    return inner
import time

def call_you(name):
    time.sleep(2)
    print(‘I call you %s‘ %name)

def outter(func):

        def wrapper(*args, **kwargs):
            start_time = time.time()
            res = func(*args, **kwargs)
            stop_time = time.time()
            print(‘The running time is %s‘ %(stop_time - start_time))
            return res
        return wrapper

call_you = outter(call_you)

call_you(‘Puppy‘)

四、装饰器语法糖

  语法糖意指那些没有给计算机添加新功能,只是对人类来说更加“甜蜜”的语法,能够增加程序的可读性,减少代码出错的机会。

# 注意语法糖的放置位置,放在要用的函数的顶部,要用@开头

五、认证装饰器实现

  1. 加入认证模块的简单实现:

  2. 加入认证模块后登陆进行验证:

 

六、叠加多个装饰器

# 注意多个装饰器的顺序,按照顺序执行

  1. 认证装饰器

  

  2. 计时装饰器

  

  3. 叠加多个装饰器(注意先后顺序)

七、带参装饰器

带参数,可以让装饰器有更大的灵活性。上面写的无参装饰器唯一的参数就是执行对应的业务函数。装饰器的语法允许我们在调用的时候,提供其他参数。新增的参数为装饰器的编写和使用提供了更大的灵活性。

上面的use_logging是允许带参数的装饰器。它实际上是对原有装饰器的 一个函数封装,并返回一个装饰器。我们可以将它理解为一个含有参数的闭包。

当我们调用的时候,Python能够发现这一层封装,并把参数传递到装饰器的环境中。

原文地址:https://www.cnblogs.com/JetpropelledSnake/p/8671220.html

时间: 2024-10-01 04:26:01

Python入门之函数的装饰器的相关文章

python入门(六)装饰器的理解

装饰器用于拓展原有函数功能的一种函数比如: def helloWorld(fun) def out() print ("======start========") fun() print ("=====end======") return out @helloWorld def back () print ("let's go") back() 运行结果: ======start======== let's go =====end====== b

Python高阶函数之 - 装饰器

高阶函数:  1. 函数名可以作为参数传入     2. 函数名可以作为返回值. python装饰器是用于拓展原来函数功能的一种函数 , 这个函数的特殊之处在于它的返回值也是一个函数 , 使用python装饰器的好处就是在不用更改原函数代码的前提下给函数增加新的功能, 装饰器的原理即是闭包. 原文地址:https://www.cnblogs.com/chenbin93/p/8988712.html

python 高阶函数与装饰器

高阶函数定义1.函数接收的参数是一个函数名2.函数的返回值是一个函数名以上两者满足任意一个,就是高阶函数 装饰器定义本质就是函数,功能是为其他函数添加新功能 装饰器的原则 1.不修改被装饰函数的源代码(开放封闭原则) 2.为被装饰函数添加新功能后,不修改被修饰函数的调用方式 装饰器=高阶函数+函数嵌套+闭包     # 无返回值无参数 import time def timer(func): #func = test def w(): start_time = time.time() func(

python中高阶函数与装饰器(2)

函数返回值为内置函数名: def sum(*args):    def sum_in():        ax = 0        for n in args:            ax = ax + n        return ax    return sum_in 当我们调用sum()时,返回的并不是求和结果,而是求和函数: >>> f = sum(1, 3, 5, 7, 9) >>> f <function sum.<locals>.su

python day4笔记 常用内置函数与装饰器

1.常用的python函数 abs             求绝对值 all               判断迭代器中所有的数据是否为真或者可迭代数据为空,返回真,否则返回假 any             判断迭代器中的数据是否有一个为真,有返回真,可迭代数据为空或者没有真,返回假 bin             转换整数为二进制字符串 hex            转换整数为十六进制字符串 oct             转换整数为八进制字符串 bool           转换数据为布尔值

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

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

python学习笔记之函数总结--高阶函数以及装饰器

python学习笔记之函数总结--高阶函数以及装饰器 Python特点: 1.不是纯函数式编程(允许变量存在): 2.支持高阶函数(可以传入函数作为变量): 3.支持闭包(可以返回函数): 4.有限度的支持匿名函数: 高阶函数: 1.变量可以指向函数: 2.函数的参数可以接收变量: 3.一个函数可以接收另一个函数作为参数: 下面我将示例一些函数的写法以及使用,并说明python中函数的特性: 1.基本的高阶函数示例: #!/usr/bin/env python def func():      

python学习笔记4:高阶函数,装饰器,生成器,迭代器

一.高级函数1.把一个函数名当作实参传给另一个函数2.返回值包含函数名>>> def bar():... print ("in the bar")... >>> def foo(func):... res=func()... return res... >>> foo(bar)in the bar 二.嵌套函数在函数中定义另一个函数 三.装饰器装饰器本质上是函数,作用是装饰其他函数,就是为其他函数添加附加功能.原则1:不能修改被装饰

五、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