Python中的闭包

def calc_sum(lst):def lazy_sum():return sum(lst)return lazy_sum

像这种内层函数引用了外层函数的变量(参数也算变量),然后返回内层函数的情况,称为闭包(Closure)。在函数内部定义的函数和外部定义的函数是一样的,只是他们无法被外部访问

闭包的特点是返回的函数还引用了外层函数的局部变量,所以,要正确使用闭包,就要确保引用的局部变量在函数返回后不能变

def count():fs = []for i in range(1, 4):def f(i):               # 必须传入参数,生成局部变量,否则调用外层函数变量可变return lambda: i*i  # 返回一个匿名函数,也叫 lambda单行表达式fs.append(f(i))return fs
f1, f2, f3 = count()
print f1(), f2(), f3()

匿名函数

上述代码中lambda表达式表示简单的单行函数,方便定义,并且只在函数内部定义使用。

lambda 表达式必须使用 lambda 关键字进行定义。在 lambda 关键字之后、冒号左边的是参数列表,可以没有参数,也可以有多个参数。如果有多个参数,则需要用逗号隔开,冒号右边是该 lambda 表达式的返回值。

匿名函数有个限制,就是只能有一个表达式,不写return,返回值就是该表达式的结果。

函数返回时也可以返回匿名函数,如:

myabs = lambda x: -x if x < 0 else x
myabs(-1)  # 1

decorator 装饰器

当需要给原函数 f 增加功能时,不需要直接修改原函数。Python的 decorator 本质上就是一个高阶函数,它接收一个函数作为参数,然后,返回一个新函数。

高阶函数参考:https://blog.csdn.net/Qianzhen_Sun/article/details/105345949

使用 decorator 时,用Python提供的 @ 语法,这样可以避免手动编写 f = decorate(f) 这样的代码。彻底屏蔽原函数功能。
举例:

def log(f):def fn(x):print 'call ' + f.__name__ + '()...'return f(x)return fn@log                    # 该语法等同于 factorial = log(factorial)
def factorial(n):return reduce(lambda x,y: x*y, range(1, n+1))
print factorial(10)"""
打印结果
call factorial()...
3628800
"""

要让 @log 自适应任何参数定义的函数,可以利用 Python 的 *args (可变参数,返回一个 tuple)和 **kw (关键字参数,返回一个 dict),保证任意个数的参数总是能正常调用:

def log(f):def fn(*args, **kw):print 'call ' + f.__name__ + '()...'return f(*args, **kw)return fn

编写带参数的 decorator

def log(prefix):                     # 传入参数def log_decorator(f):def wrapper(*args, **kw):print '[%s] %s()...' % (prefix, f.__name__)return f(*args, **kw)return wrapperreturn log_decorator@log('DEBUG')
def test():pass
print test()

上面的调用等同于带参数的log函数首先返回一个decorator函数,再让这个decorator函数接收my_func并返回新函数。不利用@,拆开调用形式如下:

log_decorator = log('DEBUG')
@log_decorator
def test():pass
print test()

完善 decorator

decorator 改变了函数名,还改变了函数的__doc__等其它属性。如果要让调用者看不出一个函数经过了@decorator的“改造”,就需要把原函数的一些属性复制到新函数中:

def log(f):def wrapper(*args, **kw):print 'call...'return f(*args, **kw)wrapper.__name__ = f.__name__   # 原函数信息复制过来wrapper.__doc__ = f.__doc__return wrapper

这样写 decorator很不方便,因为我们也很难把原函数的所有必要属性都一个一个复制到新函数上,所以 Python内置的functools可以用来自动化完成这个“复制”的任务:

import functools
def log(f):@functools.wraps(f)           # 完成复制任务def wrapper(*args, **kw):print 'call...'return f(*args, **kw)return wrapper

Python 的偏函数

functools.partial可以把一个参数多的函数变成一个参数少的新函数,少的参数需要在创建时指定默认值,这样,新函数调用的难度就降低了。

自定义转换2进制函数:

def int2(x, base=2):return int(x, base)

可以通过 functools.partial 函数进行转化:

import functools
int2 = functools.partial(int, base=2)
import functools   # 自定义忽略大小写排序
sorted_ignore_case = functools.partial(sorted, key=str.lower)
print sorted_ignore_case(['bob', 'about', 'Zoo', 'Credit'])

整理不易,点赞支持!

Python 中的闭包、匿名函数、decorator 装饰器与python的偏函数相关推荐

  1. python函数式编程:匿名函数,装饰器,偏函数

    一 匿名函数: 尽管python的语法已经很简洁,但是定义函数的过程还是相对繁琐,当我们在调用函数的过程中,python为我们提供了可以节省定义函数时间的方法,让我们可以不用显示的调用函数,那就是匿名 ...

  2. Python中的property类和@property装饰器

    Python中的property类和@property装饰器 在Python的类中,为了避免使用者直接在类的外部操作属性和方法,我们可以将属性和方法设置成私有属性和私有方法. 如果我们需要访问私有属性 ...

  3. day4 匿名函数、装饰器、生成器、迭代器、内置函数、 json 与 pickle 模块

    文章目录 1.列表生成式 2.匿名函数 3.装饰器 4.生成器 5.迭代器 6.内置函数 7.json & pickle 序列化与反序列化 1.列表生成式 可通过特定语句便捷生成列表 list ...

  4. python 三个内置装饰器,python中自带的三个装饰器

    说到装饰器,就不得不说python自带的三个装饰器: 1.@property 将某函数,做为属性使用 @property 修饰,就是将方法,变成一个属性来使用. class A(): @propert ...

  5. Python自学记录——返回函数、匿名函数、装饰器与偏函数

    国庆节快乐~~虽说今天是假期的最后一天.. 好久没学习Python了..值得高兴的是 <怪物猎人:世界>目前所有的龙我(统枪)都打过一遍了 (/得意). 正题,开始学习.记录: 返回函数 ...

  6. Python-回调函数、匿名函数和装饰器

    Python-回调函数和装饰器 0 前言 1 回调函数 2 匿名函数 2.1 匿名函数一般格式 2.2 匿名函数分支格式 2.3 匿名函数被调用 3 装饰器 3.1 不带参数的装饰器 3.2 带参数的 ...

  7. 【python】匿名函数与装饰器

    1. 匿名函数 语法:lambda [arg1 [,arg2,.......argn]]:expression注意点:arg1:参数名,可以带多个,参数名之间都逗号隔开expression : 表达式 ...

  8. 【Python】Python中的lambda匿名函数

    语法格式: lambda params:expr 注意事项: lambda只是一个表达式,函数体比def的简单很多. lambda的主体是一个表达式,而不是一个代码块.仅仅能在lambda表达式中封装 ...

  9. python中的lambda匿名函数

    先看下面的这段代码. s="hello world " (lambda x: x.split())(s)#将英文句子x单词化. 结果 上面定义了一个匿名函数. 使用lambda的语 ...

最新文章

  1. 炎热夏天到底如何让自己更凉快? - 生活至上,美容至尚!
  2. 计算机程序水仙花数,水仙花数
  3. mysql 必知必会 笔记
  4. CSS基础语法(三) CSS的6种特性
  5. LeetCode 1178. 猜字谜(状态压缩+枚举二进制子集+哈希)
  6. 天气预报API接口 : 城市对应码(中国天气网)
  7. 把数据库中的数据制作成Excel数据
  8. bzoj 3519: [Zjoi2014] 消棋子 题解
  9. python电脑下载安装-python
  10. MVC模式在Java Web应用程序中的实现
  11. bom头mysql_BOM信息头详解
  12. 用html设计logo,网页设计中的logo设计方法
  13. 在Openjdk 8 中如何合理使用容器 memory 资源
  14. Alkyne-PEG2000-Maleimide,含有炔基和马来西安亚楠的PEG,Alk-PEG2000-MAL
  15. Halcon条形码识别
  16. .ul>li 和 .ul li的区别
  17. matlab hanning和hann,哪位大侠能告知——为什么在MATLAB2012中不能调研(汉宁)窗函...
  18. 二月、三月校招面试复盘总结(二)
  19. 软件外包公司的优缺点
  20. Unix编程常见问题解答(精华)

热门文章

  1. java护照号码校验_SpringBoot如何优雅的校验参数
  2. 049、准备overlay网络实验环境(2019-03-14 周四)
  3. React解决长列表方案(react-virtualized)
  4. 康普在金色一号中心缔造光纤新历史
  5. 利用angular4和nodejs-express构建一个简单的网站(六)—用户模块和路由分析
  6. 新浪微博开放平台开发-android客户端(2)
  7. mariadb集群初次启动方法
  8. 详细解读神经网络十大误解,再也不会弄错它的事情原理
  9. JS 内置对象DATE的方法
  10. 删除文件时,提示没权限删除文件怎么办