#装饰器,类似面向对象设计模式里的静态代理模式
'''
Python的 decorator 本质上就是一个高阶函数,它接收一个函数作为参数,然后,返回一个新函数。
使用 decorator 用Python提供的 @ 语法,这样可以避免手动编写 f = decorate(f) 这样的代码。
'''
def log(f):
def fn(x):
print 'call ' + f.__name__ + '()...'
return f(x)
return fn
@log
def factorial(n):
return reduce(lambda x,y: x*y, range(1, n+1))
print factorial(10)
运行结果:
call factorial()...
3628800
但如果被装饰的函数有多个参数,则要换个写法。
def log2(f):
'''
*args 容纳任意变量的list
**kw 容纳任意key,value的dict
'''
def fn(*args, **kw):#可接收任何参数
print 'call ' + f.__name__ + '()...'
return f(*args, **kw)
return fn
@log2
def add(x, y):
return x + y
print add(1, 2)
运行结果:call add()...
3
但如果装饰器需要传参,则又得改代码:
import time
def performance(unit):
def cget(fc): #以此来传fc
def gtime(*args, **kw):
if unit == 'ms':
lt = int(round(time.clock()*1000))
fv = fc(*args, **kw)
print 'call %s() in %d ms' % (fc.__name__, int(round(time.time()*1000))-lt)
return fv
return gtime
return cget
#含参数的装饰器
@performance('ms')
def factoriall(n):
return reduce(lambda x,y: x*y, range(1, n+1))
print factoriall(10)
运行结果:call factoriall() in 1468813702849 ms
3628800
装饰器的逻辑很简单,就是在某段操作执行前做一些事,类似AOP的前置通知。可以将一些共性操作提取出来,作为装饰者。
内层函数引用了外层函数的变量(参数也算变量),然后返回内层函数的情况,称为闭包(Closure)。
闭包的特点就是内层函数引用了外层函数的局部变量,所以,要正确使用闭包,就要确保引用的局部变量在函数返回后不能变。
至于闭包,有个经典栗子。
def count():
fs = []
for i in range(1, 4):
def f():
return i*i
fs.append(f)
return fs
f1, f2, f3 = count()
print f1(),f2(),f3()
运行结果:9 9 9
def count1():
fs = []
for i in range(1, 4):
def f(m=i):
return m*m
fs.append(f)
return fs
f1, f2, f3 = count1()
print f1(),f2(),f3()
运行结果:1 4 9
异常处理就简单举个栗子:
try:
a = 8/0
except Exception,ex:
print Exception,":",ex
运行结果:
<type 'exceptions.Exception'> : integer division or modulo by zero