python中函数总结之装饰器闭包详解

作者:jingxian 时间:2023-06-27 02:55:04 

1、前言

函数也是一个对象,从而可以增加属性,使用句点来表示属性。

如果内部函数的定义包含了在外部函数中定义的对象的引用(外部对象可以是在外部函数之外),那么内部函数被称之为闭包。

2、装饰器

装饰器就是包装原来的函数,从而在不需要修改原来代码的基础之上,可以做更多的事情。

装饰器语法如下:


@deco2
@deco1
def func(arg1,arg2...):
 pass

这个表示了有两个装饰器的函数,那么表示的含义为:func = deco2(deco1(func))

无参装饰器语法如下:


@deco
def func():
 pass

表示的含义为func = deco(func)

有参装饰器语法如下:


@deco(deco_args)
def func():
 pass

表示的含义为:func = deco(deco_args)(func)

多个装饰器有的有参数有的没参数,语法如下:


@deco2(arg1,arg2)
@deco1
def func():
 pass

表示的含义为foo = deco2(arg1,arg2)deco1(func)

装饰器实际上就是函数,接受的也是函数对象。

在执行函数之前,可以运行预备代码,也可以在执行代码后做一些清理工作。

看见装饰器的时候,很可能在里面找到一些代码,它定义了某个函数,并在定义内的某处嵌入了对目标函数的调用或者至少一点引用。

3、装饰器作用

装饰器的作用如下:

引入日志;增加计时逻辑来检测性能;给函数加入了事物的能力

以下例子表示为引入了计时的逻辑来检测性能,如下:


#!/usr/bin/env python

from time import ctime,sleep

def tsfunc(func): #装饰器函数接受的是一个函数对象
 def wrappedFunc():
   print '[%s] %s() called' % (ctime(),func.__name__)
   return func() #在这里调用了函数对象,也就是表示装饰器是装饰了原来的函数,从而在原来函数的基础上进行了一些操作
 return wrappedFunc

@tsfunc #装饰器
def foo():
 pass

foo()
sleep(4)

for i in range(2):
 sleep(1)
 foo()

 执行结果如下:


[root@python 420]# python deco.py
[Tue Apr 19 16:15:01 2016] foo() called
[Tue Apr 19 16:15:06 2016] foo() called
[Tue Apr 19 16:15:07 2016] foo() called

在装饰器函数中,增加了时间戳并且调用了目标函数,装饰器的返回值是一个包装了函数

4、闭包

如果在一个内部函数里,对在外部作用于(但不是全局作用域)的变量进行引用,那么内部函数被认为是闭包closure,定义在外部函数内的但由内部函数引用或者使用的变量称之为自由变量。

闭包的主要作用如下:

安装计算;隐藏状态;在函数对象和作用域中随意的切换。

回调就是函数,闭包也是函数,但是能携带一点额外的作用域。


#!/usr/bin/env python

def counter(start_at=0):
 count = [start_at]
 def incr():
   count[0] += 1
   return count[0]
 return incr

count= counter(5)
print count()
print count()

在上面的例子可以看到,函数内部的函数incr引用了外部的变量count,并且每次进行加一,从而这个变量count称之为自由变量。

标签:python,闭包,装饰器
0
投稿

猜你喜欢

  • python二维图制作的实例代码

    2021-09-17 21:29:35
  • mysql 8.0.17 安装配置图文教程

    2024-01-14 11:44:16
  • Python切片操作深入详解

    2021-07-06 08:39:26
  • pytorch中的卷积和池化计算方式详解

    2021-03-31 19:26:32
  • docker上安装使用mysql镜像

    2024-01-24 21:04:15
  • 微软:跑分速度不是IE8的开发重点

    2008-09-12 12:10:00
  • 解决使用pip安装报错:Microsoft Visual C++ 14.0 is required.

    2022-05-02 14:42:15
  • pytorch如何利用ResNet18进行手写数字识别

    2022-02-07 04:07:26
  • css基础教程属性篇之二

    2008-07-25 19:23:00
  • ASP UTF-8页面乱码+GB2312转UTF-8 +生成UTF-8格式的文件(编码)

    2011-04-19 11:15:00
  • Mybatis应用mysql存储过程查询数据实例

    2024-01-16 09:05:52
  • Python深度学习之Pytorch初步使用

    2023-08-12 08:16:41
  • Python写一个简单的在线编辑器

    2022-07-26 22:49:17
  • pandas 两列时间相减换算为秒的方法

    2022-04-15 00:30:07
  • python中使用zip函数出现<zip object at 0x02A9E418>错误的原因

    2021-02-24 02:37:14
  • 使用Python进行数独求解详解(一)

    2023-12-25 09:39:20
  • django使用多个数据库的方法实例

    2024-01-21 00:11:34
  • 详解python实现识别手写MNIST数字集的程序

    2021-05-01 13:17:40
  • HTML:scrollLeft,scrollWidth,clientWidth,offsetWidth完全详解

    2024-04-22 22:25:25
  • MS SQL2000 数据库自动备份方法

    2010-07-22 19:52:00
  • asp之家 网络编程 m.aspxhome.com