目录

  • 1闭包
  • 2装饰器
    • 2.1装饰器功能
    • 2.2示例
      • 1无参数的函数
      • 2被装饰的函数有参数
      • 3被装饰的函数有不定长参数
      • 4装饰器中的return
      • 5装饰器带参数,在原有装饰器的基础上,设置外部变量
      • 6类装饰器(扩展,非重点)

1闭包

在函数内部再定义一个函数,并且这个函数用到了外边函数的变量,那么将这个函数以及用到的一些变量称之为闭包。

# 定义一个函数
def test(number):# 在函数内部再定义一个函数,并且这个函数用到了外边函数的变量,那么将这个函数以及用到的一些变量称之为闭包def test_in(number_in):print("in test_in 函数, number_in is %d" % number_in)return number+number_in# 其实这里返回的就是闭包的结果return test_in# 给test函数赋值,这个20就是给参数number
ret = test(20)# 注意这里的100其实给参数number_in
print(ret(100))#注 意这里的200其实给参数number_in
print(ret(200))

运行结果:

in test_in 函数, number_in is 1002
120

in test_in 函数, number_in is 200
220

例子

def line_conf(a, b):def line(x):return a*x + breturn lineline1 = line_conf(1, 1)
line2 = line_conf(4, 5)
print(line1(5))
print(line2(5))

这个例子中,函数line与变量a,b构成闭包。在创建闭包的时候,我们通过line_conf的参数a,b说明了这两个变量的取值,这样,我们就确定了函数的最终形式(y = x + 1和y = 4x + 5)。我们只需要变换参数a,b,就可以获得不同的直线表达函数。由此,我们可以看到,闭包也具有提高代码可复用性的作用。如果没有闭包,我们需要每次创建直线函数的时候同时说明a,b,x。这样,我们就需要更多的参数传递,也减少了代码的可移植性。注意点:由于闭包引用了外部函数的局部变量,则外部函数的局部变量没有及时释放,消耗内存。

2装饰器

# 定义函数:完成包裹数据
def makeBold(fn):def wrapped():return "<b>" + fn() + "</b>"return wrapped# 定义函数:完成包裹数据
def makeItalic(fn):def wrapped():return "<i>" + fn() + "</i>"return wrapped@makeBold
def test1():return "hello world-1"@makeItalic
def test2():return "hello world-2"@makeBold
@makeItalic
def test3():return "hello world-3"print(test1())
print(test2())
print(test3())

运行结果:

上面@makeBold的作用就是等价于test1=makeBold(test1),多个按照先入后出的顺序进行。

2.1装饰器功能

引入日志
函数执行时间统计
执行函数前预备处理
执行函数后清理功能
权限校验等场景
缓存

2.2示例

1无参数的函数

from time import ctime, sleepdef timefun(func):def wrapped_func():print("%s called at %s" % (func.__name__, ctime()))func()return wrapped_func@timefun
def foo():print("I am foo")foo()
sleep(2)
foo()

上面代码可以理解为:

foo = timefun(foo)
# foo先作为参数赋值给func后,foo接收指向timefun返回的wrapped_func
foo()
# 调用foo(),即等价调用wrapped_func()
# 内部函数wrapped_func被引用,所以外部函数的func变量(自由变量)并没有释放
# func里保存的是原foo函数对象

2被装饰的函数有参数

from time import ctime, sleepdef timefun(func):def wrapped_func(a, b):print("%s called at %s" % (func.__name__, ctime()))print(a, b)func(a, b)return wrapped_func@timefun
def foo(a, b):print(a+b)foo(3,5)
sleep(2)
foo(2,4)

3被装饰的函数有不定长参数

from time import ctime, sleepdef timefun(func):def wrapped_func(*args, **kwargs):print("%s called at %s"%(func.__name__, ctime()))func(*args, **kwargs)return wrapped_func@timefun
def foo(a, b, c):print(a+b+c)foo(3,5,7)
sleep(2)
foo(2,4,9)

4装饰器中的return

from time import ctime, sleepdef timefun(func):def wrapped_func():print("%s called at %s" % (func.__name__, ctime()))func()return wrapped_func@timefun
def foo():print("I am foo")@timefun
def getInfo():return '----hahah---'foo()
sleep(2)
foo()print(getInfo())


一般情况下为了让装饰器更通用,可以有return

5装饰器带参数,在原有装饰器的基础上,设置外部变量

from time import ctime, sleepdef timefun_arg(pre="hello"):def timefun(func):def wrapped_func():print("%s called at %s %s" % (func.__name__, ctime(), pre))return func()return wrapped_funcreturn timefun# 下面的装饰过程
# 1. 调用timefun_arg("itcast")
# 2. 将步骤1得到的返回值,即time_fun返回, 然后time_fun(foo)
# 3. 将time_fun(foo)的结果返回,即wrapped_func
# 4. 让foo = wrapped_fun,即foo现在指向wrapped_func
@timefun_arg("itcast")
def foo():print("I am foo")@timefun_arg("python")
def too():print("I am too")foo()
eep(2)
too()

可以理解为:foo()==timefun_arg(“itcast”)(foo)()

6类装饰器(扩展,非重点)

装饰器函数其实是这样一个接口约束,它必须接受一个callable对象作为参数,然后返回一个callable对象。在Python中一般callable对象都是函数,但也有例外。只要某个对象重写了 __ call__() 方法,那么这个对象就是callable的。

class Test(object):def __init__(self, func):print("---初始化---")print("func name is %s"%func.__name__)self.__func = funcdef __call__(self):print("---装饰器中的功能---")self.__func()
#说明:
#1. 当用Test来装作装饰器对test函数进行装饰的时候,首先会创建Test的实例对象
#   并且会把test这个函数名当做参数传递到__init__方法中
#   即在__init__方法中的属性__func指向了test指向的函数
#
#2. test指向了用Test创建出来的实例对象
#
#3. 当在使用test()进行调用时,就相当于让这个对象(),因此会调用这个对象的__call__方法
#
#4. 为了能够在__call__方法中调用原来test指向的函数体,所以在__init__方法中就需要一个实例属性来保存这个函数体的引用
#   所以才有了self.__func = func这句代码,从而在调用__call__方法中能够调用到test之前的函数体
@Test
def test():print("----test---")
test()
showpy()#如果把这句话注释,重新运行程序,依然会看到"--初始化--"

运行结果如下:

—初始化—
func name is test
—装饰器中的功能—
----test—

python提高——闭包、装饰器相关推荐

  1. python高级-闭包-装饰器

    闭包内容: 匿名函数:能够完成简单的功能,传递这个函数的引用,只有功能 普通函数:能够完成复杂的功能,传递这个函数的引用,只有功能 闭包:能够完成较为复杂的功能,传递这个闭包中的函数以及数据,因此传递 ...

  2. SIGIA_4P python学习 列表 字典 集合 面对对象编程 闭包 装饰器 函数式编程 作用域 异常处理

    SIGIA_4P python学习 列表 字典 集合 面对对象编程 闭包 装饰器 函数式编程 作用域 异常处理 本文连接 简介 SIGIA_4P 网址 a. 课程OKR Objectives and ...

  3. python高阶函数闭包装饰器_Python_基础_(装饰器,*args,**kwargs,高阶函数,函数闭包,函数嵌套)...

    一,装饰器 装饰器:本质就是函数,功能是为其它的函数动态添加附加的功能 原则:对修改关闭对扩展开放 1.不修改被修饰函数的源代码 2.不修改被修改函数的调用方式 装饰器实现的知识储备:高阶函数,函数嵌 ...

  4. 初学者python笔记(装饰器、高阶函数、闭包)

    一个函数被定义完成后,甚至程序发布后,后期可能需要添加某些功能,但是我们不可能每次都去修改原函数的代码,这时候装饰器就可以上场了,本篇文章将会用一个个可实现的代码,由浅入深.循序渐进得阐述装饰器的强大 ...

  5. python入门day11闭包装饰器

    目录 闭包 例子 同级闭包 装饰器引入 装饰器使用 无参例子 有参例子 可变参数例子 带关键字参数的装饰器 双层装饰器 装饰器带参数 装饰器的应用 闭包 def func():a=100def inn ...

  6. Python深入05 装饰器

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 装饰器(decorator)是一种高级Python语法.装饰器可以对一个函数.方法 ...

  7. 一文搞懂Python知识难点------装饰器

    1.装饰器的本质 装饰器本质上是一个闭包函数,可以让其它函数在不需要任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数. 闭包函数 1)必须是嵌套函数,即外函数中定义了一个内函数: 2)内函 ...

  8. Python学习之==装饰器

    在Python中,装饰器和迭代器.生成器都是非常重要的高级函数. 在讲装饰器之前,我们先要学习以下三个内容: 一.函数的作用域 1.作用域介绍 Python中的作用域分为四种情况: L:local,局 ...

  9. python装饰器原理-python 中的装饰器及其原理

    装饰器模式 此前的文章中我们介绍过装饰器模式: 装饰器模式中具体的 Decorator 实现类通过将对组建的请求转发给被装饰的对象,并在转发前后执行一些额外的动作来修改原有的部分行为,实现增强 Com ...

  10. python装饰器类-PYTHON里的装饰器能装饰类吗

    扩展回答 如何理解python里的装饰器 通常可以理解它是一个hook 的回调函数. 或者是理解成python 留给二次开发的一个内置API. 一般是用回调和hook 方式实现的. 如何理解Pytho ...

最新文章

  1. OpenCV 【二十】给图像添加边界
  2. MFC调用批处理文件(.bat)
  3. Kubernetes — 容器与镜像
  4. alphac测试和bata测试区别_电缆识别仪与电缆故障测试仪的区别
  5. 技术分享 | 混合云模式下SaaS端前端最佳实践
  6. html select不能修改,更改HTML Select元素的选定选项
  7. 解耦与人类行为 (完整)
  8. ASP.NET 缓存 Cache
  9. 吴恩达深度学习神经网络基础编程作业Logistic Regression with a Neural Network mindset
  10. Cocos2dx 之 PhysicsHandler 简单实现
  11. maven向本土仓库导入jar包(处理官网没有的jar包)
  12. 图像CMYK模式转RGB模式
  13. 利用IPSec/L2TP代理上网
  14. 争议带货达人董明珠:直播带货476亿 却被质疑经销商刷单
  15. 单核CPU仍然存在线程安全问题
  16. 项目经理在团队不同阶段的领导风格
  17. 推荐一个文献翻译软件--Deja Vu X
  18. 带哨兵的冒泡排序_冒泡排序(Bubble Sort)
  19. Python是强语言类型还是弱语言类型
  20. QT解决报错registered using qRegisterMetaType()

热门文章

  1. pycharm创建django项目界面解释
  2. php遗漏,PHP被遗漏的执行函数
  3. php语言输出九九乘法表_PHP 输出九九乘法表
  4. oracle打开 txt文件,oracle 导入txt文件
  5. LeetCode 1114. 按序打印
  6. Python之 break退出循环
  7. 验证Java编程环境是否成功时出现“'javac'不是内部或外部命令,也不是可运行的程序或批处理文件”
  8. 【Qt串口调试助手】1.4 - 16进制接收/发送
  9. 树莓派入门教程 - 0 - 准备篇 - 0.3 树莓派串口访问终端
  10. IO流 (一) ----- 基本概念和FIle类