【装饰器】

1、最简单的Decorator。

def author(f):
def addName():
print('My name is xkfx.\n')
f()
return addName @author
def helloWorld():
print('Hello, World')

@log放到now()函数的定义处,相当于执行了语句:helloWorld = author(helloWorld)。

>>> helloWorld()
My name is xkfx. Hello, World

这个时候查看函数的名字会发现

>>> helloWorld.__name__
'addName'

2、稍微修改一下

def author(f):
def addName():
print('My name is xkfx.[edition-2]\n')
return f()
return addName
@author
def helloWorld():
print('Hello, World')
>>> helloWorld()
My name is xkfx.[edition-2] Hello, World

将直接调用f();改为return f();执行效果是一样的,先打印author name然后执行原函数。

3、这个时候希望由用户输入author名,也就是包装器要接收一个字符串参数,那该怎么办?这就需要一个嵌套的decorator:

def author(authorName):
def decorator(func):
def wrapper(*args, **kw): # wrapper是包装纸的意思
print("author:" + authorName)
return func() # 调用原函数,注意是有括号的
return wrapper # 返回包装后的函数
return decorator # 返回真正的包装器
>>> from test import author
>>> @author('xkfx')
... def printHello():
... print('Hello\n')
...
>>> printHello()
author:xkfx
Hello

查看被包装后的函数名:

>>> printHello.__name__
'wrapper'

需要把原始函数的__name__等属性复制到wrapper()函数中,否则,有些依赖函数签名的代码执行就会出错。而做这件事情本身也属于“拓展函数功能”的范畴,用Python库内置的装饰器完成就可以了。只需记住在定义wrapper()的前面加上@functools.wraps(func)即可,如下所示:

import functools

def author(authorName):
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kw): # wrapper是包装纸的意思
print("author:" + authorName)
return func() # 调用原函数,注意是有括号的
return wrapper # 返回包装后的函数
return decorator # 返回真正的包装器

再走一遍流程:

>>> printHello.__name__
'printHello'

4、练习。

import functools

def log(func):
@functools.wraps(func)
def wrapper(*args, **kw):
print('begin call')
result = func(*args, **kw)
print('after call')
return result
return wrapper @log
def f():
pass

需求二不会做。

【偏函数】

当函数的参数太多的时候,可以选择将部分参数固定来简化函数,固定的方式就是使用functools模块中的partial函数。

一个简单的例子,固定谈话对象:

def say(words, name):
print(words + ',' + name)

原函数需要两个参数:

>>> say('hello', 'xkfx')
hello,xkfx

经简化后得到的“偏”函数只需要传入一个参数就够了:

>>> say2 = functools.partial(say, name='xkfx')
>>> say2('hi')
hi,xkfx

当然固定多个参数肯定是可行的,(实际上是将要固定关键字参数传入了一个隐式的dict)

>>> say2 = functools.partial(say, name='xkfx', age=19)
>>> say2('hi')
hi,xkfx
Your age is 19

【Python】装饰器 & 偏函数的更多相关文章

  1. python装饰器的简单理解

    如果你接触 Python 有一段时间了的话,想必你对 @ 符号一定不陌生了,没错 @ 符号就是装饰器的语法糖. 装饰器的使用方法很固定: 先定义一个装饰函数(帽子)(也可以用类.偏函数实现) 再定义你 ...

  2. 关于python装饰器

    关于python装饰器,不是系统的介绍,只是说一下某些问题 1 首先了解变量作用于非常重要 2 其次要了解闭包 def logger(func): def inner(*args, **kwargs) ...

  3. python装饰器通俗易懂的解释!

    1.python装饰器 刚刚接触python的装饰器,简直懵逼了,直接不懂什么意思啊有木有,自己都忘了走了多少遍Debug,查了多少遍资料,猜有点点开始明白了.总结了一下解释得比较好的,通俗易懂的来说 ...

  4. Python 装饰器学习

    Python装饰器学习(九步入门)   这是在Python学习小组上介绍的内容,现学现卖.多练习是好的学习方式. 第一步:最简单的函数,准备附加额外功能 1 2 3 4 5 6 7 8 # -*- c ...

  5. python 装饰器修改调整函数参数

    简单记录一下利用python装饰器来调整函数的方法.现在有个需求:参数line范围为1-16,要求把9-16的范围转化为1-8,即9对应1,10对应2,...,16对应8. 下面是例子: def fo ...

  6. python 装饰器学习(decorator)

    最近看到有个装饰器的例子,没看懂, #!/usr/bin/python class decorator(object): def __init__(self,f): print "initi ...

  7. Python装饰器详解

    python中的装饰器是一个用得非常多的东西,我们可以把一些特定的方法.通用的方法写成一个个装饰器,这就为调用这些方法提供一个非常大的便利,如此提高我们代码的可读性以及简洁性,以及可扩展性. 在学习p ...

  8. 关于python装饰器(Decorators)最底层理解的一句话

    一个decorator只是一个带有一个函数作为参数并返回一个替换函数的闭包. http://www.xxx.com/html/2016/pythonhexinbiancheng_0718/1044.h ...

  9. Python装饰器由浅入深

    装饰器的功能在很多语言中都有,名字也不尽相同,其实它体现的是一种设计模式,强调的是开放封闭原则,更多的用于后期功能升级而不是编写新的代码.装饰器不光能装饰函数,也能装饰其他的对象,比如类,但通常,我们 ...

  10. Python装饰器与面向切面编程

    今天来讨论一下装饰器.装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等.装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数 ...

随机推荐

  1. 第1章 部署虚拟环境安装linux系统

    章节简述: 本章节带领读者从0基础了解虚拟机软件与红帽系统,完整的演示了在VM与KVM中安装红帽RHEL7系统的方法. 特别增加了超级实用的Linux系统找回root密码.虚拟机功能增强包.VNC远程 ...

  2. Excel单元格格式设置

    工作中遇到一些小问题: 例如办公自动化里的如何设置单元格格式 此格式分为两种:一种是样式上的格式 比如边框 行距字体等 第二种为数据格式: 比如每次我输入1000的话自动变红或者加粗字体 office ...

  3. json、jsonp的定义和区别

    一.区别 简单来说,json是一种数据交换格式,jsonp是一种非官方跨域数据交互协议.json描述的是信息的格式,而jsonp是信息传递双方约定的方法.json返回的是一串数据,而 jsonp返回的 ...

  4. Bootstrap中关于input里file的样式更改

    给input里file类型加button样式 1.在Bootstrap中input里的file类型样式很不美观,一个按钮加一段文字,还会随浏览器的不同呈现不同的样式,所以开发的时候可以将file的样式 ...

  5. hibernate的.hbm.xml文件文件配置属性详解

    一般.hbm.xml文件如下面: <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "- ...

  6. HTML5跨平台开发环境配置

    http://hi.baidu.com/kuntakinte/item/1bbd3759b4901a3695eb050c

  7. Delphi编写下载程序:UrlDownloadToFile的进度提示

    urlmon.dll中有一个用于下载的API,MSDN中的定义如下: HRESULT URLDownloadToFile(             LPUNKNOWN pCaller,       L ...

  8. DNS服务简介

    一.域名系统 1.域名系统概述 域名系统DNS(Domain Name System)是因特网使用的命名系统,用来把便于人们使用的机器名字转换成为IP地址.域名系统其实就是名字系统.为什么不叫“名字” ...

  9. PHP函数addslashes和mysql_real_escape_string的区别

    转自:http://www.jb51.net/article/49205.htm   这篇文章主要介绍了PHP函数addslashes和mysql_real_escape_string的区别,以及一个 ...

  10. [报错]Unable to simultaneously satisfy constraints

    项目中自定义Cell,控件使用autoLayout来设置约束,发现运行页面表现正常,但是控制台报如下错误: Unable to simultaneously satisfy constraints. ...