本篇内容

  1. 什么是装饰器

  2. 装饰器需要遵循的原则

  3. 实现装饰器的知识储备

  4. 高阶函数

  5. 函数嵌套

  6. 闭包函数

  7. 无参函数

  8. 装饰器示例

1.什么是装饰器

器即函数

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

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

2.装饰器需要遵循的原则

1.不修改被装饰函数的源代码(开放封闭原则)

2.为被装饰函数添加新功能后,不修改被修饰函数的调用方式

3.实现装饰器的知识储备

装饰器=高阶函数+函数嵌套+闭包

4.高阶函数

高阶函数定义:
1.函数接收的参数是一个函数名

2.函数的返回值是一个函数名

3.满足上述条件任意一个,都可称之为高阶函数

# 接收的参数是一个函数名
def count(func,num):
num=func(num)
print(num) count(abs,-10) # 输出
# 10
# 返回值是一个函数
def count():
print('输出数字的绝对值方法:')
return abs put=count()
print(put(-10)) # 输出
# 输出数字的绝对值方法:
# 10

高阶函数总结
1.函数接收的参数是一个函数名
  作用:在不修改函数源代码的前提下,为函数添加新功能,
  不足:会改变函数的调用方式
2.函数的返回值是一个函数名
  作用:不修改函数的调用方式
  不足:不能添加新功能

5.函数嵌套

之前写过,去看看吧,我觉得写得还挺好的。

函数基础:

http://www.cnblogs.com/40kuai/articles/6374356.html

6.闭包函数

闭包是由函数及其相关的引用环境组合而成的实体(即:闭包=函数+引用环境)(想想Erlang的外层函数传入一个参数a, 内层函数依旧传入一个参数b, 内层函数使用a和b, 最后返回内层函数

函数是什么
地球人都知道:函数只是一段可执行代码,编译后就“固化”了,每个函数在内存中只有一份实例,得到函数的入口点便可以执行函数了。在函数式编程语言中,函 数是一等公民(First class value:第一类对象,我们不需要像命令式语言中那样借助函数指针,委托操作函数),函数可以作为另一个函数的参数或返回值,可以赋给一个变量。函数可 以嵌套定义,即在一个函数内部可以定义另一个函数,有了嵌套函数这种结构,便会产生闭包问题。如:

>>> def ExFunc(n):
sum=n
def InsFunc():
return sum+1
return InsFunc >>> myFunc=ExFunc(10)
>>> myFunc()
11
>>> myAnotherFunc=ExFunc(20)
>>> myAnotherFunc()
21
>>> myFunc()
11
>>> myAnotherFunc()
21
>>>

在这段程序中,函数InsFunc是函数ExFunc的内嵌函数,并且是ExFunc函数的返回值。我们注意到一个问题:内嵌函数InsFunc中 引用到外层函数中的局部变量sum,IronPython会这么处理这个问题呢?先让我们来看看这段代码的运行结果。当我们调用分别由不同的参数调用 ExFunc函数得到的函数时(myFunc(),myAnotherFunc()),得到的结果是隔离的,也就是说每次调用ExFunc函数后都将生成并保存一个新的局部变量sum。其实这里ExFunc函数返回的就是闭包。

引用环境
按照命令式语言的规则,ExFunc函数只是返回了内嵌函数InsFunc的地址,在执行InsFunc函数时将会由于在其作用域内找不到sum变量而出 错。而在函数式语言中,当内嵌函数体内引用到体外的变量时,将会把定义时涉及到的引用环境和函数体打包成一个整体(闭包)返回。现在给出引用环境的定义就 容易理解了:引用环境是指在程序执行中的某个点所有处于活跃状态的约束(一个变量的名字和其所代表的对象之间的联系)所组成的集合。闭包的使用和正常的函 数调用没有区别。

由于闭包把函数和运行时的引用环境打包成为一个新的整体,所以就解决了函数编程中的嵌套所引发的问题。如上述代码段中,当每次调用ExFunc函数 时都将返回一个新的闭包实例,这些实例之间是隔离的,分别包含调用时不同的引用环境现场。不同于函数,闭包在运行时可以有多个实例,不同的引用环境和相同 的函数组合可以产生不同的实例。

6.1 闭包函数定义

python中的闭包从表现形式上定义(解释)为:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure).

>>>def addx(x):
>>> def adder(y): return x + y
>>> return adder
>>> c = addx(8)
>>> type(c)
<type 'function'>
>>> c.__name__
'adder'
>>> c(10)
18

结合这段简单的代码和定义来说明闭包:
如果在一个内部函数里:adder(y)就是这个内部函数,
对在外部作用域(但不是在全局作用域)的变量进行引用:x就是被引用的变量,x在外部作用域addx里面,但不在全局作用域里,
则这个内部函数adder就是一个闭包。  

6.2 闭包函数的注意事项

1.闭包中是不能修改外部作用域的局部变量的

>>> def foo():
... m = 0
... def foo1():
... m = 1
... print m
...
... print m
... foo1()
... print m
...
>>> foo()
0
1
0
# 从执行结果可以看出,虽然在闭包里面也定义了一个变量m,但是其不会改变外部函数中的局部变量m。

2.以下这段代码是在python中使用闭包时一段经典的错误代码

def foo():
a = 1
def bar():
a = a + 1
return a
return bar

这段程序的本意是要通过在每次调用闭包函数时都对变量a进行递增的操作。但在实际使用时没有把参数传给闭包函数。

其他详细见:http://www.cnblogs.com/JohnABC/p/4076855.html

7.无参函数

无参装饰器=高级函数+函数嵌套

无参装饰器=高级函数+函数嵌套

基本框架

1 #这就是一个实现一个装饰器最基本的架子
2 def timer(func):
3 def wrapper():
4 func()
5 return wrapper

加上参数

1 def timer(func):
2 def wrapper(*args,**kwargs):
3 func(*args,**kwargs)
4 return wrapper

加上功能

import time
def timer(func):
def wrapper(*args,**kwargs):
start_time=time.time()
func(*args,**kwargs)
stop_time=time.time()
print('函数[%s],运行时间是[%s]' %(func,stop_time-start_time))
return wrapper

加上返回值

import time
def timer(func):
def wrapper(*args,**kwargs):
start_time=time.time()
res=func(*args,**kwargs)
stop_time=time.time()
print('函数[%s],运行时间是[%s]' %(func,stop_time-start_time))
return res
return wrapper

使用装饰器

def cal(array):
res=0
for i in array:
res+=i
return res cal=timer(cal)
cal(range(10))

语法糖@

@timer  #@timer就等同于cal=timer(cal)
def cal(array):
res=0
for i in array:
res+=i
return res cal(range(10))

小知识点:

# import functools
# @functools.wraps(func)
# 被装饰器调用过的函数帮助信息显示为装饰器的帮助信息
# 调入functools模块可以解决该问题

8.装饰器示例

无参装饰器
带参装饰器

抄袭地址:http://www.cnblogs.com/linhaifeng/articles/6140395.html

Python【第四课】 装饰器的更多相关文章

  1. Python(四)装饰器、迭代器&生成器、re正则表达式、字符串格式化

    本章内容: 装饰器 迭代器 & 生成器 re 正则表达式 字符串格式化 装饰器 装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等.装饰器是解 ...

  2. python设计模式之内置装饰器使用(四)

    前言 python内部有许多内建装饰器,它们都有特别的功能,下面对其归纳一下. 系列文章 python设计模式之单例模式(一) python设计模式之常用创建模式总结(二) python设计模式之装饰 ...

  3. python函数与方法装饰器

    之前用python简单写了一下斐波那契数列的递归实现(如下),发现运行速度很慢. def fib_direct(n): assert n > 0, 'invalid n' if n < 3 ...

  4. 【笔记】Python基础五:装饰器

    一,什么是装饰器 本质就是函数,功能是为其他函数添加附加功能 原则: 1,不修改被修饰函数的源代码 2,不修改被修饰函数的调用方式 例子: import time def timmer(func): ...

  5. Python高级--闭包与装饰器

    前言:在Python中,闭包是一种非常有用的功能!它通常与装饰器一起搭配使用,可以在不改变被装饰函数的功能的基础上,完成更多的功能.如权限认证. 一.如何定义闭包 1.闭包就是两个嵌套的函数,外层函数 ...

  6. Python中利用函数装饰器实现备忘功能

    Python中利用函数装饰器实现备忘功能 这篇文章主要介绍了Python中利用函数装饰器实现备忘功能,同时还降到了利用装饰器来检查函数的递归.确保参数传递的正确,需要的朋友可以参考下   " ...

  7. guxh的python笔记三:装饰器

    1,函数作用域 这种情况可以顺利执行: total = 0 def run(): print(total) 这种情况会报错: total = 0 def run(): print(total) tot ...

  8. python 3.x 的装饰器笔记

    今天学到了python的装饰器,感觉这个东西还是稍微有些复杂,所以记录下来,方便以后的查找.虽然标题是python 3.x的装饰器,但是我也没有怎么用过python 2.x,感觉上应该是和python ...

  9. python 中多个装饰器的执行顺序

    python 中多个装饰器的执行顺序: def wrapper1(f1): print('in wrapper1') def inner1(*args,**kwargs): print('in inn ...

  10. Python函数编程——闭包和装饰器

    Python函数编程--闭包和装饰器 一.闭包 关于闭包,即函数定义和函数表达式位于另一个函数的函数体内(嵌套函数).而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量.参数.当其中一个 ...

随机推荐

  1. RAID 损坏后如何对物理硬盘做完整镜像

    "磁盘阵列是由很多价格较便宜的磁盘,组合成一个容量巨大的磁盘组,利用个别磁盘提供数据所产生加成效果提升整个磁盘系统效能.利用这项技术,将数据切割成许多区段,分别存放在各个硬盘上." ...

  2. iis / asp.net 使用 .config 和 .xml 文件的区别

    由于在项目中有同学使用后缀为 .xml 的文件作为配置文件,而配置文件中有一些敏感信息被记录,如接口地址,Token,甚至还有数据库连接字符串. 以前都没想过为何微软会使用.config 的后缀在作为 ...

  3. sql2008r2,以前好好可以用的,但装了vs2017后,连接不上了,服务也停了,结果手动也 启动不了, 无法加载或初始化请求的服务提供程

    日志: 2017-12-14 12:33:17.53 服务器 A self-generated certificate was successfully loaded for encryption.2 ...

  4. ll的命令后面的字段详解

    linux学习 命令ll后字段的解释 分类:linux | 标签: 命令ll后字段的解释  2010-10-25 15:47阅读(4513)评论(0) ls -l 列表信息详解 我们平时用ls -l ...

  5. Java NIO之选择器

    1.简介 前面的文章说了缓冲区,说了通道,本文就来说说 NIO 中另一个重要的实现,即选择器 Selector.在更早的文章中,我简述了几种 IO 模型.如果大家看过之前的文章,并动手写过代码的话.再 ...

  6. CURL学习总结(1)

    1.curl是什么?         百度百科定义:     curl是利用URL语法在命令行方式下工作的开源文件传输工具.它被广泛应用在Unix.多种Linux发行版中,并且有DOS和Win32.W ...

  7. jquery实现链接的title快速出现

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...

  8. tar命令-vi编辑器-磁盘分区及格式化-软链接及硬链接文件

    一.tar命令 1.将用户信息数据库文件和组信息数据库文件纵向合并为一个文件/1.txt(覆盖) [root@localhost  /] #  cat  /etc/passwd  /etc/group ...

  9. SpringBoot(四):banner的控制

    banner在springboot中是一个支持可配(banner的样式,banner的颜色,banner的内容).是否显示. 1)banner显示内容配置: 默认springboot如果在src/re ...

  10. SpringBoot(二):设置springboot同一接口程序启动入口

    根据上一篇文章中搭建了一个springboot简单工程,在该工程中编写HelloWordController.java接口类,并在该类中写了一个main函数,做为该类的接口服务启动入口.此时如果新增多 ...