在python中,装饰器、生成器和迭代器是特别重要的高级函数   https://www.cnblogs.com/yuanchenqi/articles/5830025.html

装饰器

  1.如果说装饰器是取经路上的大妖怪,想要干掉它就必须拿到三样法宝

法宝一:作用域(LEGB)

法宝二:高阶函数:(把函数名看作变量,可以作为传输参数,也可以作为返回值)

(在python的世界里,函数和我们之前的[1,2,3],'abc',8等一样都是对象,

而且函数是最高级的对象(对象是类的实例化,可以调用相应的方法,函数是包含变量对象的对象,牛逼!)。)

法宝三:闭包 (LEGB规则的特例,闭包实现了enclosing变量在enclosing范围之外的使用)

闭包(closure)是函数式编程的重要的语法结构。

定义:如果在一个内部函数里(local),对在外部作用域(但不是在全局作用域)的变量(enclosing)进行引用,

   那么内部函数就被认为是闭包(closure).

   闭包=函数块+定义函数时的环境,inner就是函数块,x就是环境,当然这个环境可以有很多,不止一个简单的x

def f_outer():
x=10 #enclosing变量(外部环境)
def f_inner(): #内部函数(local)
print (x)
return f_inner #enclosing变量 f_outer()() 输出结果:10

闭包(closure)

2.装饰器(从实现功能出发理解)

装饰器本质上是一个函数,该函数用来处理其他函数,它可以让其他函数在不需要修改代码的前提下增加额外的功能,装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等应用场景。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。

概括的讲,装饰器的作用就是在不修改源代码的情况下为已经存在的对象添加额外的功能

1.重新定义一个函数,为原函数添加功能

2.需要外加一个装饰器(函数)用来传递原函数,然后返回step1中定义的函数

3.如果还需要传其它参数,可以再外加一个装饰器传递参数

简单装饰器的实现

if  foo()==show_time(foo) :问题解决!

所以,我们需要show_time(foo)返回一个函数对象,而这个函数对象内则是核心业务函数:执行func()与装饰函数时间计算,修改如下:

函数show_time就是装饰器,它把真正的业务方法func包裹在函数里面,看起来像foo被上下时间函数装饰了。在这个例子中,函数进入和退出时 ,被称为一个横切面(Aspect),这种编程方式被称为面向切面的编程(Aspect-Oriented Programming)。

 import time
def foo():
print('Function1')
time.sleep(5) def bar():
print('Function2')
time.sleep(5) def show_time(func):
def inner():
start=time.time()
func()
end=time.time()
print(end-start)
return inner
foo=show_time(foo)
bar=show_time(bar) foo()
bar()

闭包实现

@符号是装饰器的语法糖,在定义函数的时候使用,避免再一次赋值操作

 import time
def show_time(func):
def inner():
start=time.time()
func()
end=time.time()
print(end-start)
return inner @show_time
def foo():
print('Function1')
time.sleep(5) @show_time
def bar():
print('Function2')
time.sleep(5) # foo=show_time(foo)
# bar=show_time(bar) foo()
bar()
输出结果:
Function1
5.000344753265381
Function2
5.00098443031311

@

如上所示,这样我们就可以省去bar = show_time(bar)这一句了,直接调用bar()即可得到想要的结果。如果我们有其他的类似函数,我们可以继续调用装饰器来修饰函数,而不用重复修改函数或者增加新的封装。这样,我们就提高了程序的可重复利用性,并增加了程序的可读性。

这里需要注意的问题:  foo=show_time(foo)其实是把wrapper引用的对象引用给了foo,而wrapper里的变量func之所以可以用,就是因为wrapper是一个闭包函数。

(从宏观的角度理解)

带参数的被装饰函数

 import time
def show_time(func):
def inner(x,y):
start=time.time()
func(x,y)
end=time.time()
print(end-start)
return inner
@show_time
def add(a,b):
print(a+b)
time.sleep(5) add(2,3)
输出结果:
5

定长参数

 import time
def show_time(func):
def inner(*args,**kwargs):
start=time.time()
func(*args)
end=time.time()
print(end-start)
return inner
@show_time
def add(*args,**kwargs):
sum=0
for i in args:
sum+=i
print(sum)
time.sleep(5) add(2,3,4,5,6) 输出结果:
20

不定长参数

 带参数的装饰器

装饰器还有更大的灵活性,例如带参数的装饰器:

在上面的装饰器调用中,比如@show_time,该装饰器唯一的参数就是执行业务的函数。

装饰器的语法允许我们在调用时,提供其它参数,比如@decorator(a)。

 import time
def time_logger(flag=0):
def show_time(func):
def inner(*args,**kwargs):
start=time.time()
func(*args,**kwargs)
end=time.time()
print(end-start)
if flag:
print('打印日志')
return inner
return show_time
@time_logger(3)
def add(*args,**kwargs):
sum=0
for i in args:
sum+=i
print(sum)
time.sleep(5) add(2,3,4,5,6) 输出结果:
20
5.000020742416382
打印日志

带参数的装饰器

(说明可以通过装饰器给闭包传输参数)

3.装饰器的应用举例之登录

Day11 Python基础之装饰器(高级函数)(九)的更多相关文章

  1. 十. Python基础(10)--装饰器

    十. Python基础(10)--装饰器 1 ● 装饰器 A decorator is a function that take a function as an argument and retur ...

  2. 1.16 Python基础知识 - 装饰器初识

    Python中的装饰器就是函数,作用就是包装其他函数,为他们起到修饰作用.在不修改源代码的情况下,为这些函数额外添加一些功能,像日志记录,性能测试等.一个函数可以使用多个装饰器,产生的结果与装饰器的位 ...

  3. python基础之 装饰器,内置函数

    1.闭包回顾 在学习装饰器之前,可以先复习一下什么是闭包? 在嵌套函数内部的函数可以使用外部变量(非全局变量)叫做闭包! def wrapper(): money =10 def inner(num) ...

  4. [python基础]关于装饰器

    在面试的时候,被问到装饰器,在用的最多的时候就@classmethod ,@staticmethod,开口胡乱回答想这和C#的static public 关键字是不是一样的,等面试回来一看,哇,原来是 ...

  5. 【Python成长之路】python 基础篇 -- 装饰器【华为云分享】

    [写在前面] 有时候看到大神们的代码,偶尔会用到@来装饰函数.当时查了资料,大致了解装饰器一般用于在不改变原函数的基础上 ,对原函数功能进行修改/增强.使用场景是:日志级别设置.权限校验.性能测试等. ...

  6. python基础(8)-装饰器函数&进阶

    从小例子进入装饰器 统计一个函数执行耗时 原始版本 import time # time模块有提供时间相关函数 def do_something(): print("do_something ...

  7. python基础之装饰器(实例)

    1.必备 #### 第一波 #### def foo(): print 'foo' foo #表示是函数 foo() #表示执行foo函数 #### 第二波 #### def foo(): print ...

  8. 【Python基础】装饰器的解释和用法

    装饰器的用法比较简单,但是理解装饰器的原理还是比较复杂的,考虑到接下来的爬虫框架中很多用到装饰器的地方,我们先来讲解一下. 函数 我们定义了一个函数,没有什么具体操作,只是返回一个固定值 请注意一下缩 ...

  9. 学习PYTHON之路, DAY 5 - PYTHON 基础 5 (装饰器,字符格式化,递归,迭代器,生成器)

    ---恢复内容开始--- 一 装饰器 1 单层装饰器 def outer(func): def inner(): print('long') func() print('after') return ...

随机推荐

  1. c/c++ 多态的实现原理分析

    多态的实现原理分析 当类里有一个函数被声明成虚函数后,创建这个类的对象的时候,就会自动加入一个__vfptr的指针, __vfptr维护虚函数列表.如果有三个虚函数,则__vfptr指向的是第一个虚函 ...

  2. python3爬虫抓取智联招聘职位信息代码

    上代码,有问题欢迎留言指出. # -*- coding: utf-8 -*- """ Created on Tue Aug 7 20:41:09 2018 @author ...

  3. 利用python搭建Powersploit powershell脚本站点

    powershell脚本站点的搭建 一.Powersploit Powersploit是一款基于powershell的后渗透(Post-Exploitation)框架,集成大量渗透相关模块和功能. 下 ...

  4. mysql中的升序和降序以及一个字段升序和一个字段降序

    mySql中,升序为asc,降序为desc.例如: 升序:select   *  from  表名 order by  表中的字段 asc(mysql中默认是升序排列,可不写) 降序:select   ...

  5. python反向生成数据库模型类

    之前去的一家公司,去的时候项目已经好了,但是需要我根据数据库做一个后台管理系统,管理用户和其他的一些数据. 直接说方法 django框架 python manage.py inspectdb > ...

  6. Java 7 for Absolute Beginners/Java 7基础教程--读后感

    1. 很适合部分初学者,因为书中对于JAVA许多特性都有涉猎,而且也是浅尝即止.如果读者没有受过专业的编程训练,那么在阅读此书时不会畏惧.因为书中没有充斥着大量的计算机理论知识,虽然作者依然覆盖了JA ...

  7. nginx+keepalived高可用及双主模式

    高可用有2中方式. 1.Nginx+keepalived 主从配置 这种方案,使用一个vip地址,前端使用2台机器,一台做主,一台做备,但同时只有一台机器工作,另一台备份机器在主机器不出现故障的时候, ...

  8. css absolute同时设置top bottom

    css absolute同时设置top bottom 确定div的高度,若设置了左边框,那么这条边框的高度将随着父定位上下文高度的变大而变大 http://www.webfront-js.com/ar ...

  9. 基于mycat高可用方案——数据库负载

    引言 传统企业级应用一般采取单台数据库,吞吐所有应用的读写,随着互联网的高速发展,以及微服务架构越来越普及,往往采用分库分表来支撑高速增长的大量业务数据吞吐.分库分表主要有两种方式:水平分表和垂直分库 ...

  10. (转)Spring Boot 2 (六):使用 Docker 部署 Spring Boot 开源软件云收藏

    http://www.ityouknow.com/springboot/2018/04/02/docker-favorites.html 云收藏项目已经开源2年多了,作为当初刚开始学习 Spring ...