Python之decorator,闭包,异常

#装饰器,类似面向对象设计模式里的静态代理模式
'''
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


因为最终i已成为3,可作如下修改:
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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值