【装饰器】

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

最新文章

  1. [LintCode] Pow(x, n) 求x的n次方
  2. JDBC连接数据库操作
  3. 常用的JSTL函数
  4. 怎么在手机上查看sqlite db
  5. 升级Xcode6.4插件失效解决办法
  6. HDU-3586 Information Disturbing(树形DP+删边)
  7. Generate Parentheses java实现
  8. java集合 collection-list-ArrayList 去除ArrayList集合中的重复元素。
  9. A Tour of Go Slices
  10. Linq to Object实现分页获取数据
  11. [WPF]DataGrid C#添加右键弹出选择菜单
  12. Bash ShellShock 解决办法
  13. solr索引报错(java.lang.OutOfMemoryError:GC overhead limit exceeded)
  14. ide phpStorm更换主题
  15. Linux和Shell教程
  16. 《梦断代码》Scott Rosenberg著(二)
  17. CSS网页菜单
  18. 20145322 Exp5 MS11_050
  19. Hello World with Ant
  20. 装饰者模式——(head first 设计模式3)

热门文章

  1. 修复吾爱OD数据窗口双击不出现偏移问题
  2. Django学习笔记第四篇--数据处理URL和数据库
  3. python虚拟机运行原理
  4. 170421、maven自定义变量及属性
  5. 较快的maven的settings.xml文件
  6. Spring的Bean的生命周期以及Bean的后置处理器
  7. rrdtool ubuntu python snmpwalk
  8. SNORT--install ---dependency-resolve
  9. intellij idea 主题更换(换黑底或白底)
  10. d3.js 之关联数据:data操作符