装饰器(函数)

装饰器作为一个函数,可以为其他函数在不修改原函数代码的前提下添加新的功能

装饰器的返回值是一个函数对象。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等。

装饰器,可以让我们抽离出大量与函数功能本身无关的相同代码并在装饰器函数中使用

装饰器的三个重要要素:

一、作用域

二、高阶函数

三、闭包

一、作用域

在上一节的函数中,我们详细介绍了函数的4种作用域:

L.local,局部作用域;E.enclosing,嵌套作用域;G.global,全局作用域;B.built-in,内建作用域

作用域的优先搜索顺序:局部作用域>>外层嵌套作用域>>当前模块(嵌套函数中)的全局作用域>>python内置作用域;

二、高阶函数

把函数作为参数传入,即函数本身也可以作为一个变量,这样的函数称为高阶函数

高阶函数,就是为了让函数的参数能够接收到别的函数

三、闭包

闭包函数可以脱离函数,在函数的外部单独地进行调用

闭包 = 内部函数 + 定义函数时的环境

闭包的两个条件:1、拥有内部函数;2、对外部环境的一个变量进行引用

def outer():
x = 'Hello World!' #定义函数的变量(环境) def inner(): #条件1,,inner是内部函数
print(x) #条件2,对外部环境的一个变量进行引用 return inner #结论,内部函数inner就是一个闭包 f = outer()
f()
>>> Hello World!

装饰器

Eg1.计算总用时的装饰器

import time

def show_time(f):
def inner():
start = time.time()
f()
end = time.time()
res = end - start
print('总用时:',res)
return inner @show_time #效果相当于 func1=show_time(func1)
def func1():
print('-----------功能1-----------')
time.sleep(2) # 延时2s @show_time #效果相当于 func2=show_time(func2)
def func2():
print('-----------功能2-----------')
time.sleep(3) # 延时3s func1()
func2()
>>>-----------功能1-----------
总用时: 2.0070815086364746
-----------功能2-----------
总用时: 3.0007598400115967

Eg2.带参数的装饰器(如果被装饰的函数中有参数,则装饰器函数中也要带上参数)

import time
def show_time(f):
def inner(*args,**kwargs):
start = time.time()
f(*args,**kwargs)
end = time.time()
res = end - start
print('总用时:',res)
return inner @show_time #效果相当于 func1=show_time(func1)
def func3(*args,**kwargs):
sums = 0
for i in args:
sums += i
print('-----------加法器-----------')
print('结果是:',sums) func3(5,6,1,4)
>>>-----------加法器-----------
结果是: 16
总用时: 0.0

Eg3.带参数的装饰器(参数为设置的条件,判断是否需要执行修饰器)

import time
def flag(flag = 'False'):
def show_time(f):
def inner(*args,**kwargs):
if flag == 'True':
start = time.time()
f(*args,**kwargs)
end = time.time()
print('time: %s'%(end-start))
else:
f(*args, **kwargs)
return inner
return show_time @flag('True') # flag = 'True',运行总用时装饰器
def add(*args,**kwargs):
sum = 0
for i in args:
sum+=i
print('-----add的运行结果-----')
print(sum)
time.sleep(1) @flag('False') # flag = 'False',不运行总用时装饰器
def add1(*args,**kwargs):
sum = 0
for i in args:
sum+=i
print('-----add1的运行结果-----')
print(sum)
time.sleep(1) add(1,4)
add1(1,4)
>>> -----add的运行结果-----
5
time: 1.0008649826049805
-----add1的运行结果-----
5

注意:

  • 我们在调用装饰器时,提供了其它参数,@flag()默认的参数为False,则不会输出总用时装饰器;
  • 当@flag()参数为True时,输出总用时。这样是在原有的装饰器上加了一层判断;
  • 当我们使用@flag(‘True’)调用的时候,Python能够发现这一层的封装,并把参数传递到装饰器的环境中;

Python学习 :装饰器的更多相关文章

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

    Python学习---装饰器的学习1210 Python学习---生成器的学习1210 Python学习---迭代器学习1210

  2. Python学习---装饰器的学习1210

    装饰器的基础 学习前提: 作用域 + 函数的理解 + 闭包  [学习,理解] 代码编写原则: 对修改开放对扩展开放 装饰器本质上是一个函数,该函数用来处理其他函数,它可以让其他函数在不需要修改代码的前 ...

  3. python学习---装饰器

    什么是装饰器 器即函数 装饰即修饰,意指为其他函数添加新功能 装饰器定义:本质就是函数,功能是为其他函数添加新功能 装饰器需要遵循的原则 1.不修改被装饰函数的源代码(开放封闭原则) 2.为被装饰函数 ...

  4. python学习——装饰器函数

    一.装饰器函数的作用是什么 答:装饰器函数是在不修改原函数及其调用方式的情况下对原函数功能进行扩展 对于搞python开发的人来说,函数占据了至关重要的地位.都说学好函数你就可以去找工作了,好了,假如 ...

  5. Python学习——装饰器/decorator/语法糖

    装饰器 定义:本质是函数,为其他函数添加附加的功能. 原则:1.不能修改原函数的源代码 2.不能修改被原函数的调用方式 重点理解: 1.函数即“变量” 2.高阶函数:返回值中包含函数名 3.嵌套函数 ...

  6. day12 python学习 装饰器

    闭包函数: 内部函数包含对外部作用域而非全剧作用域名字的引用,该内部函数称为闭包函数#函数内部定义的函数称为内部函数 闭包函数获取网络应用 from urllib.request import url ...

  7. python之循序渐进学习装饰器

    python装饰器的定义:在代码运行期间在不改变原函数定义的基础上,动态给该函数增加功能的方式称之为装饰器(Decorator) 装饰器的优点和用途: 1. 抽离出大量函数中与函数功能本身无关的的雷同 ...

  8. python基础 (装饰器,内置函数)

    https://docs.python.org/zh-cn/3.7/library/functions.html 1.闭包回顾 在学习装饰器之前,可以先复习一下什么是闭包? 在嵌套函数内部的函数可以使 ...

  9. python初级装饰器编写

    最近项目太忙好久没有学习python了,今天更新一下吧~~ 1.什么是python装饰器: 装饰器本质上是一个python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外的功能,装饰器的返 ...

  10. Python之装饰器、迭代器和生成器

    在学习python的时候,三大“名器”对没有其他语言编程经验的人来说,应该算是一个小难点,本次博客就博主自己对装饰器.迭代器和生成器理解进行解释. 为什么要使用装饰器 什么是装饰器?“装饰”从字面意思 ...

随机推荐

  1. js 日期格式化及日期增减

    //Demo:new Date().format("yyyy-MM-dd hh:mm:ss.SSS") Date.prototype.format = function (form ...

  2. Intellij idea用快捷键自动生成序列化id

    ntellij idea用快捷键自动生成序列化id 类继承了Serializable接口之后,使用alt+enter快捷键自动创建序列化id 进入setting→inspections→seriali ...

  3. iotop使用详解

    iotop是top和iostat程序的混合体,能够显示系统中所有运行进程并将进程根据I/O统计信息排序. 这个软件使用了Linux内核的一些新特性,所以需要2.6.20或者更新的内核. 一般默认情况下 ...

  4. dedecms Ajax异步获取文章列表

    dedecms如何通过ajax(异步)动态获取文章列表数据. 第一步添加:服务端(PHP)代码 打开plus目录下面的list.php文件,在12行代码下面添加以下代码: if(isset($_GET ...

  5. List 的 removeAll 方法的效率

    List 的 removeAll 方法的效率低的原因: 要遍历source,对dest进行contain操作,而contain又要遍历dest进行equal比较. 解决办法:dest转为set,用se ...

  6. [EffectiveC++]item34:区分接口继承和实现继承

    [EffectiveC++]item34:区分接口继承和实现继承

  7. Shodan搜索引擎介绍

    from:http://www.exploit-db.com/wp-content/themes/exploit/docs/33859.pdf 0x00 概要 这篇文章可以作为渗透测试人员和安全工作者 ...

  8. su

    参数选项:-,-l,--login 切换用户的同时,将用户的家目录.系统环境变量等重新按切换后的用户初始化.-c 向shell传递单个命令,仅希望在某个用户下执行命令,而不用直接切换到该用户下来操作. ...

  9. Ajax三级联动操作的js代码

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...

  10. UVA12034 Race

    嘟嘟嘟 令dp[i]表示在n个人中,有 i 个人获得第一名的方案数,转移方程为dp[i] = C(i, n) * dp[n - i].C(i, n)就是从n个人中选 i 个第一,那么剩下的n - i ...